我在控制器中为我的作用域分配了两个集合;两者都来自包装RestAngular和返回承诺的服务。每个都单独返回我想要的集合,但是当我将两者都分配给$ scope时,其中一个永远不会解析(它是同一个失败的,无论它们的顺序如何)。
如果我再次通过调用违规服务登录到控制台,那么看看原始作业是否完美。
服务的工作方式基本相同:
.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;
}
}
}
])
并且控制器指定如下(我已经离开了console.log,但是删除它导致$ scope.roles永远无法解析):
.controller('ResourceCtrl', ['$scope', 'Resource', 'Role', function($scope, Resource, Role) {
$scope.roles = Role.getList();
$scope.resources = Resource.getList();
console.log(Role.getList());
}])
一切都是在Angular中完成的,所以我不认为我错过了一个$ apply - 但除非我偶然发现一个错误,否则我的代码肯定有问题......
修改
我发现了导致错误的原因,但没有解决方案。我的资源服务与角色1非常相似,但由于资源具有角色,我将角色注入资源并使用它将各个元素链接在一起。一旦我删除了该行,所有范围/承诺的内容都会回来。
我想让我回过头来:如何可靠地将服务链接在一起(例如,具有角色字段的资源可以在服务级别将相应的角色对象附加到它们)。
这是我的资源:
.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;
}
}
}
])
答案 0 :(得分:1)
不确定资源服务的来源以及是否重要。由于您在角色服务中返回承诺,您可以这样做:
.controller('ResourceCtrl', ['$scope', 'Role', function($scope, Role) {
Role.getList().then(function(roles){
$scope.roles = roles;
});
}])
或者,您可以让Angular为您解析角色(例如,如果您只是在模板中使用角色)
.controller('ResourceCtrl', ['$scope', 'Role', function($scope, Role) {
$scope.roles = Role.getList();
}])
编辑:我也注意到var _collection = [];
似乎不需要。也许你也可以发布资源服务的代码?
您的角色服务的此代码应该足够。
.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;
}
}
}
])
进一步编辑:
这个plunkr显示在角度1.2rc3中第一种方法有效: http://embed.plnkr.co/SU5UMK7jNffXWnWiV1HE/preview
但是如果你试图利用自动取消承诺(在rc3中弃用,你运气不好): http://embed.plnkr.co/zdepkLCesYkj8pXYFTN2/preview