使用 ui-router 的 resolve 将数据从 ngResource 注入控制器
Inject data from ngResource into controller with ui-router's resolve
在 angular ui-router 文档中指出,只有在所有承诺都已解决后才会实例化控制器,包括从远程服务器获取数据。
我有一个 $resource 实例:
angular.module('app')
.factory('Item', item);
item.$inject = ['$resource'];
function item($resource) {
return $resource('/items/:id/', {id: '@id'}, {
update: {method: 'PATCH'}
});
}
我定义了一个状态,它从 url 中获取一个 id 并从 REST API:
中检索数据
$stateProvider.state('item', {
url: '/item/:itemId',
templateUrl: '../components/item/item.html',
controller: 'ItemController',
resolve: {
item: function ($stateParams, Item) {
return Item.get({id: $stateParams.itemId});
}
}
})
在controller中我尝试使用一个Item参数,假设如果controller能正常工作,那么所有的数据都已经被获取了,我可以随意使用它:
angular.module('app')
.controller('ItemController', ItemController);
ItemController.$inject = ['$scope', 'item', 'Item'];
function ItemController($scope, item, Item) {
$scope.item = item;
$scope.similarItems = Item.query({item_type__id: $scope.item.item_type_detail.id});
}
但是浏览器给我这个错误:
TypeError: Cannot read property 'id' of undefined
并指向这一行,这意味着 $scope.item.item_type_detail 仍未定义,换句话说 - 未解决。
但是如果我将我的第二个 Item 调用(在控制器中)包装在 $timeout 中,比如 5000 毫秒,它会工作正常,这意味着问题不在于 ajax 调用或不正确的依赖性注入,但控制器在承诺解决之前以某种方式被实例化。
这怎么解释,我该怎么做才能解决这个问题?
Return 对解析器函数的承诺:
$stateProvider.state('item', {
url: '/item/:itemId',
templateUrl: '../components/item/item.html',
controller: 'ItemController',
resolve: {
item: function ($stateParams, Item) {
//return Item.get({id: $stateParams.itemId});
return Item.get({id: $stateParams.itemId}).$promise;
//return promise --------------------------^^^^^^^^^
}
}
})
重要的是要意识到立即调用 $resource
对象方法 returns 一个空引用。一旦数据从服务器返回,现有引用就会填充实际数据。
通过返回$promise
属性,路由器将等待来自服务器的数据。
在 angular ui-router 文档中指出,只有在所有承诺都已解决后才会实例化控制器,包括从远程服务器获取数据。
我有一个 $resource 实例:
angular.module('app')
.factory('Item', item);
item.$inject = ['$resource'];
function item($resource) {
return $resource('/items/:id/', {id: '@id'}, {
update: {method: 'PATCH'}
});
}
我定义了一个状态,它从 url 中获取一个 id 并从 REST API:
中检索数据 $stateProvider.state('item', {
url: '/item/:itemId',
templateUrl: '../components/item/item.html',
controller: 'ItemController',
resolve: {
item: function ($stateParams, Item) {
return Item.get({id: $stateParams.itemId});
}
}
})
在controller中我尝试使用一个Item参数,假设如果controller能正常工作,那么所有的数据都已经被获取了,我可以随意使用它:
angular.module('app')
.controller('ItemController', ItemController);
ItemController.$inject = ['$scope', 'item', 'Item'];
function ItemController($scope, item, Item) {
$scope.item = item;
$scope.similarItems = Item.query({item_type__id: $scope.item.item_type_detail.id});
}
但是浏览器给我这个错误:
TypeError: Cannot read property 'id' of undefined
并指向这一行,这意味着 $scope.item.item_type_detail 仍未定义,换句话说 - 未解决。
但是如果我将我的第二个 Item 调用(在控制器中)包装在 $timeout 中,比如 5000 毫秒,它会工作正常,这意味着问题不在于 ajax 调用或不正确的依赖性注入,但控制器在承诺解决之前以某种方式被实例化。 这怎么解释,我该怎么做才能解决这个问题?
Return 对解析器函数的承诺:
$stateProvider.state('item', {
url: '/item/:itemId',
templateUrl: '../components/item/item.html',
controller: 'ItemController',
resolve: {
item: function ($stateParams, Item) {
//return Item.get({id: $stateParams.itemId});
return Item.get({id: $stateParams.itemId}).$promise;
//return promise --------------------------^^^^^^^^^
}
}
})
重要的是要意识到立即调用 $resource
对象方法 returns 一个空引用。一旦数据从服务器返回,现有引用就会填充实际数据。
通过返回$promise
属性,路由器将等待来自服务器的数据。