2014-05-09 3 views
32

Mein Service ist:

myApp.service('userService', [ 
    '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) { 
    var deferred; 
    deferred = $q.defer(); 
    this.initialized = deferred.promise; 
    this.user = { 
     access: false 
    }; 
    this.isAuthenticated = function() { 
     this.user = { 
     first_name: 'First', 
     last_name: 'Last', 
     email: '[email protected]', 
     access: 'institution' 
     }; 
     return deferred.resolve(); 
    }; 
    } 
]); 

ich dies über in meiner config Datei aufrufen:

myApp.run([ 
    '$rootScope', 'userService', function($rootScope, userService) { 
    return userService.isAuthenticated().then(function(response) { 
     if (response.data.user) { 
     return $rootScope.$broadcast('login', response.data); 
     } else { 
     return userService.logout(); 
     } 
    }); 
    } 
]); 

Es ist jedoch beklagt, dass then keine Funktion ist. Bekomme ich das aufgelöste Versprechen nicht zurück?

Antwort

17

Von Ihrem Service-Methode:

function serviceMethod() { 
    return $timeout(function() { 
     return { 
      property: 'value' 
     }; 
    }, 1000); 
} 

Und in Ihrem Controller:

serviceName 
    .serviceMethod() 
    .then(function(data){ 
     //handle the success condition here 
     var x = data.property 
    }); 
+0

@BenjaminGruenbaum Ja, Sie sind richtig, ich wusste nicht, dass '$ timeout' tatsächlich eine Zusage zurückgibt, serviceMethod kann verkürzt werden zu: return $ timeout (function() {return {property: 'value'};}, 1000); – Brocco

+7

Dies kann funktionieren, aber es ist sicherlich kein empfohlener Ansatz für die Rückgabe von Versprechen –

+0

@BenjaminGruenbaum Ich tat, jetzt die Versprechen, die $ Timeout erzeugt. – Brocco

31

Geben Sie Ihr Versprechen zurück, zurückgestellt. Versprechen.
Es ist die Verspreen API, die die 'then' Methode hat.

https://docs.angularjs.org/api/ng/service/$q

Aufruf resolve kehrt nicht ein Versprechen nur signalisiert die Versprechen, dass das Versprechen gelöst wird, damit es die ‚dann‘ Logik ausführen kann.

Grundmuster wie folgt, spülen und wiederholen
http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview

<!DOCTYPE html> 
<html> 

<head> 
    <script data-require="[email protected]*" data-semver="1.3.0-beta.5" 
     src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script> 
    <link rel="stylesheet" href="style.css" /> 
    <script src="script.js"></script> 
</head> 

<body> 

<div ng-controller="test"> 
    <button ng-click="test()">test</button> 
</div> 
<script> 
    var app = angular.module("app",[]); 

    app.controller("test",function($scope,$q){ 

    $scope.$test = function(){ 
     var deferred = $q.defer(); 
     deferred.resolve("Hi"); 
     return deferred.promise; 
    }; 

    $scope.test=function(){ 
     $scope.$test() 
     .then(function(data){ 
     console.log(data); 
     }); 
    }  
    }); 

    angular.bootstrap(document,["app"]); 

</script> 

+0

Wie wird das Versprechen dann gelöst bekommen? Das '.then 'wird nie ausgelöst – Shamoon

+2

Sie lösen die zurückgestellte, bevor Sie deferred.promise zurückgeben. – mccainz

+0

@Shamoon deferred.resolve(); ist in dem Moment gelöst, in dem Sie es aufrufen, da kein Wert angegeben ist. Ich würde vorschlagen, anstatt deferred.resolve ("Hi") zu schreiben; schreibe einfach deferred.resolve(); um ein gelöstes leeres Versprechen zu bekommen. Sie könnten aber auch $ q.when(); um ein gelöstes, nüchtiges leeres Versprechen zu bekommen ;-). – Sebastian

0

Try this:

myApp.service('userService', [ 
    '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) { 
     var deferred= $q.defer(); 
     this.user = { 
     access: false 
     }; 
     try 
     { 
     this.isAuthenticated = function() { 
     this.user = { 
      first_name: 'First', 
      last_name: 'Last', 
      email: '[email protected]', 
      access: 'institution' 
     }; 
     deferred.resolve(); 
     }; 
    } 
    catch 
    { 
     deferred.reject(); 
    } 

    return deferred.promise; 
    ]); 
+0

Kann mir jemand sagen, warum dies für den Downvote markiert ist? – premsh

2

Hier ist der richtige Code für Ihren Service:

myApp.run([ 
    '$rootScope', 'userService', function($rootScope, userService) { 
    return userService.isAuthenticated().then(function(user) { 
     if (user) { 
     // You have access to the object you passed in the service, not to the response. 
     // You should either put response.data on the user or use a different property. 
     return $rootScope.$broadcast('login', user.email); 
     } else { 
     return userService.logout(); 
     } 
    }); 
    } 
]); 

Nur wenige Punkte über den Service zu beachten:

myApp.service('userService', [ 
    '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) { 

    var user = { 
     access: false 
    }; 

    var me = this; 

    this.initialized = false; 
    this.isAuthenticated = function() { 

     var deferred = $q.defer(); 
     user = { 
     first_name: 'First', 
     last_name: 'Last', 
     email: '[email protected]', 
     access: 'institution' 
     }; 
     deferred.resolve(user); 
     me.initialized = true; 

     return deferred.promise; 
    }; 
    } 
]); 

Dann Controller, den Sie entsprechend ausrichten sollten :

  • In einem Service nur exponieren, was freigelegt werden muss. Der Benutzer sollte intern gehalten werden und nur von Gettern aufgerufen werden.

  • Wenn in Funktionen, verwenden Sie 'mich', die der Service ist, um Rand Fälle von diesem mit Javascript zu vermeiden.

  • Ich vermutete, was initialisiert werden sollte, fühlen Sie sich frei, mich zu korrigieren, wenn ich falsch geraten habe.

1

Für kürzere JavaScript-Code, um diese verwenden:

myApp.service('userService', [ 
    '$q', function($q) { 
    this.initialized = $q.when(); 
    this.user = { 
     access: false 
    }; 
    this.isAuthenticated = function() { 
     this.user = { 
     first_name: 'First', 
     last_name: 'Last', 
     email: '[email protected]', 
     access: 'institution' 
     }; 
     return this.initialized; 
    }; 
    } 
]); 

Sie wissen, dass Sie die Bindung an userService.user durch Überschreiben mit einem neuen Objekt statt Einstellung nur die Objekte Eigenschaften verlieren?

Hier ist, was ich als ein Beispiel für meine PLNKR meine.Co Beispielcode (Arbeitsbeispiel: http://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview):

angular.module('myApp', []).service('userService', [ 
    '$http', '$q', '$rootScope', '$location', function ($http, $q, $rootScope, $location) { 
    this.initialized = $q.when(null); 
    this.user = { 
     access: false 
    }; 
    this.isAuthenticated = function() { 
     this.user.first_name = 'First'; 
     this.user.last_name = 'Last'; 
     this.user.email = '[email protected]'; 
     this.user.access = 'institution'; 
     return this.initialized; 
    }; 
}]); 

angular.module('myApp').controller('myCtrl', ['$scope', 'userService', function ($scope, userService) { 
    $scope.user = userService.user; 
    $scope.callUserService = function() { 
     userService.isAuthenticated().then(function() { 
      $scope.thencalled = true; 
     }); 
    }; 
}]); 
1

ein aufgelöstes Versprechen zurückzukehren, können Sie:

return $q.defer().resolve(); 

Wenn Sie etwas lösen müssen oder Daten zurückgeben:

return $q.defer().resolve(function(){ 

    var data; 
    return data; 

}); 
+0

Ich habe (gepostet) (http://stackoverflow.com/a/30779102/901944) eine noch kürzere Version. –

82

So geben Sie einfach ein voraufgelöstes Versprechen unter Winkel

zurück Gelöst Versprechen:

return $q.when(someValue); // angular 1.2+ 
return $q.resolve(someValue); // angular 1.4+, alias to `when` to match ES6 

Abgelehnt Versprechen:

return $q.reject(someValue); 
+1

Genau das habe ich gesucht. Eine nette kurze Möglichkeit, einen statischen Wert zurückzugeben, wenn HTTP-Serviceaufrufe ausgetragen werden. – Richard