AngularJS:多承诺不规律解析 [英] AngularJS: multiple promises resolving erratically

查看:99
本文介绍了AngularJS:多承诺不规律解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我分配两个集合到我在控制器范围;无论是从服务包RestAngular来回报承诺。每间单独返回我想收集,但是当我分配既$范围其中之一从来没有解决(这是相同的一个失败,无论他们所在的顺序)。

如果我登录再次调用违规服务,然后LO安慰你看原来的分配完美的作品。

这些服务都工作pretty大致相同的:

  .factory('角色',['Restangular','$ Q',函数(Restangular,$ Q){
        变种_collection = [];
        VAR _roleService = Restangular.all('角色');        返回{
            的GetList:功能(){
                //返回_roleService.getList();
                变种listDeferred = $ q.defer();
                _roleService.getList()
                。然后(功能(名单){
                    listDeferred.resolve(名单);
                    _collection =清单;
                });
                返回listDeferred.promise;
            }
        }
    }
])

和控制器规定如下(我已经离开了的console.log,但删除它会导致$ scope.roles永远不会解决):

  .controller('ResourceCtrl',['$范围,资源,角色,函数($范围,资源,角色){
    $ scope.roles = Role.getList();
    $ scope.resources = Resource.getList();    的console.log(Role.getList());
}])

一切都在角做,所以我不认为我缺少一个$应用 - 但除非我的错误绊倒必须有什么问题我的code ...

修改

我发现了什么导致了错误,但没有一个解决方案。我的资源服务是非常相似的作用,但是因为资源有角色,我注入作用到资源并用它来个别元素链接在一起。有一次,我删除了所有行范围/承诺的东西回来了。

我的猜测让我回想起:我怎么联系起来的服务可靠(即所以用角色字段资源可以在服务级别重视他们相应的角色对象)。

下面是我的资源:

  .factory('资源',['Restangular','$ Q','角色',
    功能(Restangular,$ Q,角色){
        VAR _resourceService = RestAngular.all('资源');
        VAR _roleService =作用;        VAR _convertObjectsToUrls =功能(项目){
            对于(项VAR属性){
                如果(item.hasOwnProperty(财产)及和放大器; typeof运算(项目[物业])=='对象'和;&安培;!项目[物业] = NULL){
                    项目[物业] =项目[物业]的.url;
                }
            }
            归还物品;
        }        VAR _convertUrlsToObjects =功能(项目){
            对于(项VAR属性){
                如果(item.hasOwnProperty(财产)及和放大器; typeof运算(项目[物业])=='串'和;&放大器;项目[物业] ='!'和;&安培;物业!='URL'和;&安培;项目[物业] .substr(0,4)=='HTTP'){
 / *这个换行符IT * /项目[物业] = _roleService.getByUrl(项目[物业]);
                }
            }
            归还物品;
        }        VAR _getIdFromUrl =功能(URL){
            VAR pathElements = url.split('/')
            返回pathElements [pathElements.length - 2]
        }        VAR _cleanParams =功能(项目){
            对于(项VAR属性){
                如果(item.hasOwnProperty(财产)){
                    项目[物业] =不确定;
                }
            }
            归还物品;
        }        返回{
            添加:函数(项目){
                变种responseDeferred = $ q.defer();
                项目= _convertObjectsToUrls(项目);                _resourceService.post(项目)
                。然后(功能(响应){
                    响应= _convertUrlsToObjects(响应);
                    response.name = response.first_name +''+ response.last_name;                    _collection.push(响应);
                    responseDeferred.resolve(响应);                    项目= _cleanParams(项目);
                });
                返回responseDeferred.promise;
            },
            编辑:函数(项目){
                变种responseDeferred = $ q.defer();
                VAR IDX = _collection.indexOf(项目);
                项目= _convertObjectsToUrls(项目);                item.customPUT(_getIdFromUrl(item.url))
                。然后(功能(响应){
                    响应= _convertUrlsToObjects(响应);
                    response.name = response.first_name +''+ response.last_name;                    _collection.splice(IDX,1,响应)
                    responseDeferred.resolve(响应);
                });
                返回responseDeferred.promise;
            },
            删除:函数(项目){
                变种responseDeferred = $ q.defer();
                VAR IDX = _collection.indexOf(项目);
                //项目= _convertObjectsToUrls(项目);                item.customDELETE(_getIdFromUrl(item.url),{})
                。然后(功能(响应){
                    响应= _convertUrlsToObjects(响应);                    _collection.splice(IDX,1)
                    responseDeferred.resolve(响应);
                });
                返回responseDeferred.promise;
            },
            的GetList:功能(){
                变种listDeferred = $ q.defer();
                VAR列表= _resourceService.getList()
                。然后(功能(名单){
                    _.each(列表功能(项指标,表){
                        项目= _convertUrlsToObjects(项目);
                        item.name = item.first_name +''+ item.last_name;
                    })
                    listDeferred.resolve(名单);
                    _collection =清单;
                });
                返回listDeferred.promise;
            }
        }
    }
])


解决方案

从那里资源服务来了,是否是很重要的不知道。既然你在你的角色的服务回报承诺,你可以做:

  .controller('ResourceCtrl',['$范围','角色',函数($范围,角色){
    Role.getList()。然后(功能(角色){
         $ scope.roles =角色;
    });
}])

另外,你可以让角度解析您的角色(如果你只是用在模板中的角色,例如)

  .controller('ResourceCtrl',['$范围','角色',函数($范围,角色){
      $ scope.roles = Role.getList();
 }])

编辑:我也注意到了 VAR _collection = []; 这似乎没有必要。也许你也可以张贴code为资源服务?
您的角色服务的这code应该是足够了。

  .factory('角色',['Restangular','$ Q',函数(Restangular,$ Q){
        返回{
            的GetList:功能(){
                变种listDeferred = $ q.defer();
                Restangular.all(角色)的GetList()。然后(功能(名单){
                    listDeferred.resolve(名单);
                });
                返回listDeferred.promise;
            }
        }
    }
])

更进一步编辑:

这plunkr表明,在角1.2rc3的第一种方法:
http://embed.plnkr.co/SU5UMK7jNffXWnWiV1HE/$p$pview

但是,如果你尝试采取承诺的自动unrwapping的优势(这是在RC3 pcated德$ P $,你的运气了):
http://embed.plnkr.co/zdepkLCesYkj8pXYFTN2/$p$pview

I am assigning two collections into my scope in a controller; both come from services wrapping RestAngular and return promises. Each individually returns the collection I want, but when I assign both to $scope one of them never resolves (it's the same one that fails, no matter the order they're in).

If I log to console by calling the offending service again, then lo and behold the original assignment works perfectly.

The services both work pretty much the same:

.factory('Role', ['Restangular', '$q', function(Restangular, $q){
        var _collection = [];
        var _roleService = Restangular.all('roles');

        return {
            getList: function() {
                // return _roleService.getList();
                var listDeferred = $q.defer();
                _roleService.getList()
                .then(function(list) {
                    listDeferred.resolve(list);
                    _collection = list;
                });
                return listDeferred.promise;
            }
        }
    }
])

and the controller is specified as follows (I've left the console.log in, but removing it causes $scope.roles to never resolve):

.controller('ResourceCtrl', ['$scope', 'Resource', 'Role', function($scope, Resource, Role) {
    $scope.roles = Role.getList();
    $scope.resources = Resource.getList();

    console.log(Role.getList());
}])

Everything is done within Angular so I don't think I'm missing an $apply - but unless I've stumbled on a bug there must be something wrong with my code...

EDIT

I found out what's causing the error, but don't have a solution. My Resource service is very similar to the Role one, but because Resources have Roles, I inject Role into Resource and use it to link individual elements together. Once I deleted that line all the scope / promise stuff came back.

Which I guess takes me back to: how do I link services together reliably (i.e. so Resources with role fields can have the corresponding Role objects attached to them at the service level).

Here's my Resource:

.factory('Resource', ['Restangular', '$q', 'Role',
    function(Restangular, $q, Role){
        var _resourceService = RestAngular.all('resources');
        var _roleService = Role;

        var _convertObjectsToUrls = function(item) {
            for (var property in item) {
                if (item.hasOwnProperty(property) && typeof(item[property]) == 'object' && item[property] != null) {
                    item[property] = item[property].url;
                }
            }
            return item;
        }

        var _convertUrlsToObjects = function(item) {
            for (var property in item) {
                if (item.hasOwnProperty(property) && typeof(item[property]) == 'string' && item[property] != '' && property != 'url' && item[property].substr(0,4) == 'http') {
 /* THIS LINE BREAKS IT */                       item[property] = _roleService.getByUrl(item[property]);
                }
            }
            return item;
        }

        var _getIdFromUrl = function(url) {
            var pathElements = url.split('/')
            return pathElements[pathElements.length - 2]
        }

        var _cleanParams = function(item) {
            for (var property in item) {
                if (item.hasOwnProperty(property)) {
                    item[property] = undefined;
                }
            }
            return item;
        }

        return {
            add: function(item) {
                var responseDeferred = $q.defer();
                item = _convertObjectsToUrls(item);

                _resourceService.post(item)
                .then(function(response){
                    response = _convertUrlsToObjects(response);
                    response.name = response.first_name + ' ' + response.last_name;

                    _collection.push(response);
                    responseDeferred.resolve(response);

                    item = _cleanParams(item);
                });
                return responseDeferred.promise;
            },
            edit: function(item) {
                var responseDeferred = $q.defer();
                var idx = _collection.indexOf(item);
                item = _convertObjectsToUrls(item);

                item.customPUT(_getIdFromUrl(item.url))
                .then(function(response){
                    response = _convertUrlsToObjects(response);
                    response.name = response.first_name + ' ' + response.last_name;

                    _collection.splice(idx, 1, response)
                    responseDeferred.resolve(response);
                });
                return responseDeferred.promise;
            },
            delete: function(item) {
                var responseDeferred = $q.defer();
                var idx = _collection.indexOf(item);
                // item = _convertObjectsToUrls(item);

                item.customDELETE(_getIdFromUrl(item.url), {})
                .then(function(response){
                    response = _convertUrlsToObjects(response);

                    _collection.splice(idx, 1)
                    responseDeferred.resolve(response);
                });
                return responseDeferred.promise;
            },
            getList: function() {
                var listDeferred = $q.defer();
                var list = _resourceService.getList()
                .then(function(list) {
                    _.each(list, function(item, index, list){
                        item = _convertUrlsToObjects(item);
                        item.name = item.first_name + ' ' + item.last_name;
                    })
                    listDeferred.resolve(list);
                    _collection = list;
                });
                return listDeferred.promise;
            }
        }
    }
])

解决方案

Not sure from where the Resource service comes and whether is is of importance. Since you return a promise in your Role service, you can just do:

.controller('ResourceCtrl', ['$scope', 'Role', function($scope, Role) {
    Role.getList().then(function(roles){
         $scope.roles = roles;
    });
}])

Alternatively, you can let Angular resolve the role for you (if you are just using the roles in a template, for example)

.controller('ResourceCtrl', ['$scope', 'Role', function($scope, Role) {
      $scope.roles = Role.getList();
 }])

Edit: I also noticed the var _collection = []; which seems not needed. Maybe you can also post the code for the Resource service? This code of your Role service should be sufficient.

.factory('Role', ['Restangular', '$q', function(Restangular, $q){
        return {
            getList: function() {
                var listDeferred = $q.defer();
                Restangular.all('roles').getList().then(function(list) {
                    listDeferred.resolve(list);
                });
                return listDeferred.promise;
            }
        }
    }
])

Even further edit:

This plunkr shows that in angular 1.2rc3 the first method works: http://embed.plnkr.co/SU5UMK7jNffXWnWiV1HE/preview

But if you were to try to take advantage of the automatic unrwapping of promises (which is deprecated in rc3, you are out of luck): http://embed.plnkr.co/zdepkLCesYkj8pXYFTN2/preview

这篇关于AngularJS:多承诺不规律解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆