简体   繁体   English

在Angular承诺工厂

[英]Promise factory in Angular

New to Angular, may be using promises wrong. Angular的新手,可能使用了错误的承诺。 I have a factory returning a promise: 我有一个工厂回复承诺:

.factory('myData', ['$http', '$q', function($http, $q) {
    var deferred = $q.defer();

    $http.get('/path/to/endpoint')
        .success(function(data) {
            deferred.resolve(data);
        })
        .error(function(err) {
            deferred.reject(err.what())
        });

    return deferred.promise;
}])

Now if I inject my factory somewhere I can use the promise: 现在,如果我在某处注入我的工厂,我可以使用承诺:

.controller('myController', ['$scope', 'myData', function($scope, myData) {
    myData.then(function(result) {
        $scope.data = result;
    });
}]);

This is fine, but I'm starting to use myData in several places and I don't want to be writing a new .then in every directive and controller I use the data in. After the promise is resolved I don't care about it anymore, is there any way to make myData return a promise if it's unresolved but return just the result after it's finished resolving? 这很好,但我开始在几个地方使用myData而且我不想在每个指令和控制器中编写一个新的.then我使用数据。在承诺解决后我不关心它是否有任何方法可以使myData返回一个承诺,如果它没有解决但只是在它完成解析后返回结果?

To word it another way, can myData simple be the .then result after resolution, or do I have to write a new .then every time? 换句话说, myData简单可以解析后的.then result ,还是每次都要写一个新的.then

On working with promises 与承诺一起工作

First of all your myData service can just return the call: 首先,您的myData服务可以返回呼叫:

.factory('myData', ['$http', function($http) {
    return $http.get('/path/to/endpoint').then(function(req){
       return req.data;
    });
}]);

Unwrapping values 展开值

So you know how to work with promises in Angular... But, you want something better, you want the promise to automatically unwrap with Angular's digests. 所以你知道如何使用Angular中的promises ...但是,你想要更好的东西,你希望承诺自动解开Angular的摘要。 This is tricky but it can be done. 这很棘手,但可以做到。 Note that it can be confusing in code and I don't really recommend it but here's the general idea: 请注意,它可能会在代码中混淆,我不是真的推荐它,但这是一般的想法:

Automatic unwrapping 自动展开

.factory('myData', ['$http', function($http) {
    var result = []; // initial result to return
    var p = $http.get('/path/to/endpoint').then(function(res){
       result.push.apply(result, res.data); // add all the items
    });
    result.then = p.then; // allow hooking on it
    return result; // return the array, initially empty
}]);

This would let you do something like: 这可以让你做类似的事情:

.controller('myController', ['$scope', 'myData', function($scope, myData) {
    $scope.data = myData;
}]);

Which will put an empty array there and will replace it (also causing a digest) whenever the real data arrives, you can still do myData.then in order to check if it's done loading yourself so you can use the old syntax if you need to be sure. 这将在那里放置一个空数组并将替换它(也导致摘要)每当真实数据到达时,你仍然可以执行myData.then以检查它是否已经完成加载你所以你可以使用旧的语法,如果你需要确定。

Is it a good idea? 这是个好主意吗?

Note that Angular used to do this until version 1.2 (removed completely in 1.3) but stopped doing so because automatic unwrapping was considered too magical. 请注意, Angular在 1.2版本(在1.3中完全删除)之前就已经这样做了,但是因为自动展开被认为太神奇了而停止了这样做。 You can formulate your own decisions but take note that the Angular core team decided this was not a good idea. 您可以制定自己的决定,但请注意Angular核心团队认为这不是一个好主意。 Note that things like ngResource still do this. 请注意,像ngResource这样的东西仍然这样做。

Yes, resolve the promise in your service/factory and reference the resolved promise value in your controllers instead of referencing and handling the promise in your controllers. 是的,解决服务/工厂中的承诺,并在控制器中引用已解决的承诺值,而不是在控制器中引用和处理承诺。 Hope that makes sense. 希望有道理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM