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>