Angularjs 我无法访问控制器中的$rootScope
我在Angularjs 我无法访问控制器中的$rootScope,angularjs,angularjs-scope,angularjs-rootscope,Angularjs,Angularjs Scope,Angularjs Rootscope,我在$rootScope中有一些参数,具体如下: myApp.factory('itemService', function($http) { return $http.get('/items'); }); myApp.run(function($rootScope, itemService) { itemService.success(function(response) { $rootScope.items = response; }); });
$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未定义
。我真的不知道发生了什么事
这是一个小补充<代码>项目是一个数组,包含如下对象列表:
items = [
{'name': 'spoon', 'price': 200},
{'name': 'table', 'price': 400},
{'name': 'shoe', 'price': 250}
];
我希望在我的应用程序中不断提供项目
,这样我就可以显示项目列表上的每个项目(项目),而无需向服务器发出另一个请求。我打算通过每次需要显示项目时使用$scope.item=items[$routeParams.id]
简单地显示项目来实现这一点。
我期待着使用附加到ng click
的函数或正常的#/route/:param
机制来实现这一点。
感谢您在运行块运行异步方法:
itemService.success(function(response){
$rootScope.items = response;
});
但初始化仍在进行,所以您可能在itemService成功之前访问$rootScope.items(或者它失败,并且您没有预测到这种情况)。我建议您这样做(如果您想遵循$rootScope约定..顺便说一句,这是不好的):
您正在异步进程的回调中设置
items
,因此您试图在$rootScope
实际设置之前访问items
如果在加载控制器时尝试初始化
项
,还有其他方法可以做到这一点,例如使用路由的解析块或在控制器加载时在工厂手动调用$http.get
。TypeError:$object.property未定义通常是因为对对象引用的请求在该特定对象(或其属性)之前发出已经设定好了$http
请求本质上是异步的,因此其他进程不会被阻止。显然,试图使请求同步可能会给连接速度非常慢的人带来重大问题
除此之外,污染$rootScope
通常是个坏主意。您可以在下面的文章中找到一个关于全局变量的主题,以便研究为什么$rootScope不是一个好地方
话虽如此,但在我看来,您似乎不想发出多个请求来检索相同的数据。如果是这样,您可以使用$http.get方法的缓存选项
e、 g:
这将确保信息被请求一次并放入缓存。数据可以在不同的地方访问
<div ng-controller="aCtrl as a">
{{a.items}}
</div>
<div ng-controller="bCtrl as b">
{{b.items}}
</div>
{{a.items}
{{b.items}
这给我留下了另一个“好”实践:语法的使用。它提供了在AngularJS中使用名称空间的方法
当然,这些只是小窍门,你应该总是考虑这些要求! 最后,我想出了一个解决办法。我意识到问题在于在加载的同时在displayCtrl
中提供$rootScope.items
。但是当我的html页面加载时,$rootScope.items
在我的视图中可用。
因此,我只是将item 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>
这实际解决了我的问题。我假设itemService是一个服务,它包含对资源的http调用,并在调用服务的方法时返回承诺的对象,那么调用在哪里呢?它不应该是itemService.get().succes()等等吗。此外,为什么要将数据放在rootScope上?这样会污染根示波器。您可以在displayController中完美地注入itemService?工厂包含$http.get()
,而run()包含.success
。另外,我把数据放在$rootScope中,因为我希望它在我的文件/应用程序加载后立即可用。(我认为在我发表评论时它不可用)在这种情况下,您请求对未定义(尚未设置)对象的引用,因为http get仍在进行中。无论哪种方法,你都应该升级你的工厂并从rootScope中获取数据,这是一种不好的做法,而且有大量的文档说明了原因。使用上述方法,我已经完成了这项工作,只是因为{{item.name}}
由于上述错误而不断出现。请你告诉我一个好的或最好的方法。最佳实践是质量代码的关键。我非常感激。不过,这是一个坏习惯。您应该使用$rootScope
来存储和共享数据-谢谢你把它放在外面。请指导我一个标准的方法来实现这一点,而不使用$rootScope
,存储和共享数据。好的,我已经看到了,所以你得到了一个分数,我勾选了我的答案,因为这是我一直在寻找的,我得到了,但我已经投票支持你的观点。非常感谢你的关心。我使用您的方法重新设计代码,以获得相同的结果。那么,$rootScope
在Angularjs中的角色到底是什么呢?并没有具体说明它应该用于什么,但倾向于将它用于全局变量(但即使是可以用a进行不同的解决),或者将它用于事件传播/侦听。除此之外,我基本上保留了$root,谢谢分享,我衷心感谢。
myApp.controller('displayCtrl', function($routeParams, $scope) {
$scope.item_id = $routeParams.id; //given that the route looks like '/item/:id'
});
<div ng-bind="items[item_id].name"></div>
<div ng-bind="items[item_id].price"></div>