$scope和$rootScope的区别

98

有人能解释一下 $scope 和 $rootScope 的区别吗?

我认为:

$scope:

我们可以通过使用 $scope,从特定页面的特定控制器中获取 ng-model 属性。


$rootScope

我们可以通过使用 $rootScope,在任何页面的任何控制器中获取所有的 ng-model 属性。


这个解释正确吗?还是有其他的东西需要注意?


@CodeError!你的意思是,那个链接对我的问题没有帮助,那里有$scope.$root,而不是$rootScope。 - user3484362
$rootScope是你的Angular应用程序中所有作用域层次结构的顶部。 - Angad
9个回答

95
"$rootScope" 是一个父对象,包含在网页中创建的所有 "$scope" angular 对象。

enter image description here

$scope是通过ng-controller创建的,而$rootscope是通过ng-app创建的。

enter image description here


1
ng-app上创建的$rootScope回声使用。在您的Chrome控制台中键入此表达式,它将计算为true。angular.element('#ng-app').injector()。get('$rootScope')=== angular.element('#ng-app').scope() - Gaurang Patel

72
主要区别在于对象所分配的属性的可用性。 用 $scope 分配的属性无法在定义它的控制器之外使用,而用 $rootScope 分配的属性可以在任何地方使用。
例如:如果在下面的示例中将 $rootScope 替换为 $scope,则第一个控制器中的部门属性将不会在第二个控制器中得到填充。

angular.module('example', [])
  .controller('GreetController', ['$scope', '$rootScope',
    function($scope, $rootScope) {
      $scope.name = 'World';
      $rootScope.department = 'Angular';
    }
  ])
  .controller('ListController', ['$scope',
    function($scope) {
      $scope.names = ['Igor', 'Misko', 'Vojta'];
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="example">
  <div class="show-scope-demo">
    <div ng-controller="GreetController">
      Hello {{name}}!
    </div>
    <div ng-controller="ListController">
      <ol>
        <li ng-repeat="name in names">{{name}} from {{department}}</li>
      </ol>
    </div>
  </div>
</body>


18
根据Angular的Scopes开发人员指南
每个Angular应用程序都有一个根作用域,但可能有多个子作用域。应用程序可以有多个作用域,因为某些指令创建新的子作用域(请参阅指令文档以查看哪些指令创建新作用域)。创建新作用域时,它们会作为其父作用域的子级添加。这创建了一棵树形结构,与它们附加到其中的DOM相似。
控制器和指令都引用作用域,但彼此没有引用。这种安排将控制器与指令以及DOM隔离开来。这是一个重要的观点,因为它使控制器视图无关,极大地改善了应用程序的测试过程。

16

$rootScope 是全局可用的,无论你在哪个控制器中,而 $scope 只对当前控制器及其子控制器可用。


3
在另一方面,我们可以看到;$rootScope是全局的,而$scope是本地的。当Controller被分配到一个页面时,因此可以在这里使用$scope变量,因为它绑定到该控制器。但是当我们想要在其他控制器或服务之间共享其值时,就会使用$rootScope(**有替代方法,我们可以在不使用$rootScope的情况下共享值,但在这种情况下,我们想要使用$rootScope)。
关于您关于如何定义这两个单词的第二个问题是正确的。
最后一点有些偏题,请谨慎使用$rootScope。与使用全局变量的方式类似,可能会使调试变得困难,并且您可能会在计时器或其他某个地方意外更改全局变量,从而使您的读数不正确。

2
我建议你阅读官方深入的Angular文档,了解作用域。从“Scope Hierarchies”章节开始阅读:

https://docs.angularjs.org/guide/scope

基本上,$rootScope和$scope都标识了DOM中的特定部分,在其中进行Angular操作,并且在其中声明为$rootScope或$scope的变量可用。
属于$rootScope的任何内容在整个Angular应用程序中都是全局可用的,而属于$scope的任何内容仅在该作用域适用的DOM部分中可用。 $rootScope应用于作为Angular应用程序根元素的DOM元素(因此称为$rootScope)。当您向DOM的一个元素添加ng-app指令时,该元素成为$rootScope可用的DOM的根元素。换句话说,$rootScope的属性等将在整个Angular应用程序中都可用。
Angular $scope(及其所有变量和操作)可用于应用程序中的特定DOM子集。具体来说,任何特定控制器的$scope都适用于该特定控制器已应用(使用ng-controller指令)的DOM部分。请注意,某些指令(例如ng-repeat),当应用于已应用控制器的DOM部分时,可以创建主作用域的子作用域 - 在同一控制器中 - 控制器不一定只包含一个作用域。
如果你运行 Angular 应用程序时查看生成的 HTML,你可以很容易地看到哪些 DOM 元素“包含”作用域,因为 Angular 会在任何应用了作用域的元素上添加类 ng-scope(包括应用程序的根元素 $rootScope)。
顺便说一下,$scope 和 $rootScope 前面的“$”符号只是 Angular 中保留的标识符。
请注意,使用 $rootScope 在模块和控制器之间共享变量等通常不被认为是最佳实践。JavaScript 开发人员谈论避免通过在全局范围内共享变量来“污染”全局作用域,因为如果在其他地方使用了相同名称的变量,则可能会导致冲突,而开发人员没有意识到它已经在 $rootScope 上声明了。这个问题随着应用程序规模和开发团队的增大而变得越来越重要。理想情况下,$rootScope 只包含常量或静态变量,这些变量旨在始终保持应用程序中的一致性。更好的跨模块共享方法可能是使用服务和工厂,这是另一个话题!

2

2
两者都是JavaScript对象,下图说明它们的区别。 enter image description here 注意事项: 首先,Angular应用程序会尝试在$scope中查找任何模型或函数的属性,如果在$scope中找不到该属性,则会在上层层次结构的父级作用域中搜索。如果在上层层次结构中仍然找不到该属性,则Angular会尝试在$rootscope中解析。

1
新的风格,例如 John Papa's AngularJS Styleguide,建议我们不应该使用$scope来保存当前页面的属性。相反,我们应该使用controllerAs with vm方法,其中视图将绑定到控制器对象本身。然后在使用controllerAs语法时,使用一个捕获变量来代替this。选择一个一致的变量名,例如vm,表示ViewModel。
但是,您仍然需要$scope来进行观察。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接