我在$rootScope
中有一些参数,如下所示:
myApp.factory('itemService', function($http) {
return $http.get('/items');
});
myApp.run(function($rootScope, itemService) {
itemService.success(function(response) {
$rootScope.items = response;
});
});
myApp.controller('displayCtrl', function($rootScope, $scope) {
$scope.items = $rootScope.items;
});
当我运行上面的代码时,我从firebug得到了这个错误
TypeError: $rootScope.items is undefined
。我真的不知道发生了什么。
这是一个小小的补充。 items
是一个包含如下对象列表的数组:
items = [
{'name': 'spoon', 'price': 200},
{'name': 'table', 'price': 400},
{'name': 'shoe', 'price': 250}
];
我希望在我的应用中不断提供items
,以便我可以在项目列表(项目)上显示每个项目,而无需向服务器发出其他请求。我打算通过每次需要显示项目时使用$scope.item = items[$routeParams.id]
显示项目来实现此目的。
我期待使用附加到ng-click
的函数或普通#/route/:param
机制来实现此功能。
感谢
答案 0 :(得分:2)
TypeError: $object.property is undefined
通常是因为在设置了特定对象(或其属性)之前对对象的引用进行了请求。 $http
请求本质上是异步的,因此其他进程不会被阻止。显而易见的是,尝试使请求同步可能会给连接速度很慢的人带来严重问题。
除此之外,污染$rootScope
通常是一个坏主意。您可以在以下link上找到有关全局变量的主题,以便您调查$ rootScope不是一个好地方的原因。
说了这么多,在我看来,你并不想要多次请求来检索相同的数据。如果是这样,您可以使用$ http.get方法的缓存选项。
e.g:
myApp.factory('itemService', function($http, $q) {
return {
get: function() {
return $http({
url: 'items.json',
cache: true //keep the result in memory
});
}
};
})
myApp.controller('aCtrl', function(itemService) {
var self = this;
itemService.get().success(function(data) {
self.items = data;
});
});
myApp.controller('bCtrl', function(itemService) {
var self = this;
itemService.get().success(function(data) {
self.items = data;
});
});
这将确保信息被请求一次并放入缓存中。可以在不同的地方访问数据。
<div ng-controller="aCtrl as a">
{{a.items}}
</div>
<div ng-controller="bCtrl as b">
{{b.items}}
</div>
这让我有另一个好的&#39;练习:使用controllerAs语法。这提供了一种在AngularJS中使用命名空间的方法。
当然,这些只是提示,你应该始终考虑要求!
答案 1 :(得分:0)
您在运行块中运行异步方法:
itemService.success(function(response){
$rootScope.items = response;
});
但是初始化仍然存在,所以可能在itemService成功之前访问$ rootScope.items(或者它失败了,你没有预测到这种情况)。我建议你这样做(如果你想跟随$ rootScope召集......顺便说一下这很糟糕):
$rootScope.items = [];
itemService.success(function(response){
$rootScope.items = response;
});
答案 2 :(得分:0)
您正在异步流程的回调中设置items
,因此您在实际设置之前尝试访问items
上的$rootScope
。
如果您在加载控制器时尝试初始化items
,则还有其他方法可以执行此操作,例如使用路径的解析块或在工厂时手动调用$http.get
控制器加载。
答案 3 :(得分:0)
最后,我能够提出一个解决方案。我意识到问题是$rootScope.items
在加载的同时displayCtrl
可用。但是当我的html页面加载时,我的视图中可以使用$rootScope.items
。
所以我只是将项目ID作为参数传递,并使用$routeParams
获取它,如下所示
myApp.controller('displayCtrl', function($routeParams, $scope) {
$scope.item_id = $routeParams.id; //given that the route looks like '/item/:id'
});
然后在我的HTML文件中这就是我做的
<div ng-bind="items[item_id].name"></div>
<div ng-bind="items[item_id].price"></div>
这实际解决了我的问题。