$ scope和$ rootScope之间的区别


90

谁能解释$ scope和$ rootScope之间的区别?

我认为

$ scope:

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


$ rootScope

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


这样对吗?还是其他?


@CodeError!您是什么意思,该链接对我的问题

$ rootScope在您的角度应用程序中所有作用域的层次结构顶部。
Angad

Answers:


87

“ $ rootScope”是在网页中创建的所有“ $ scope”角度对象的父对象。

在此处输入图片说明

$ scope用创建,ng-controller而$ rootscope用创建ng-app

在此处输入图片说明


67

主要区别在于分配给对象的属性的可用性。分配有属性的属性$scope不能在定义它的控制器之外使用,而分配有属性的属性$rootScope可以在任何地方使用。

示例:如果在下面的示例中,您将$rootScope$scopeDepartment属性替换,则不会从第二个控制器中的第一个控制器填充

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的范围开发人员指南

每个Angular应用程序只有一个根范围,但可能有多个子范围。该应用程序可以具有多个作用域,因为某些指令会创建新的子作用域(请参阅指令文档以了解哪些指令会创建新的作用域)。创建新作用域时,它们将作为其父作用域的子代添加。这将创建一个树形结构,该树形结构与附加了DOM的DOM平行。

控制器和指令都引用了作用域,但没有相互引用。这种安排将控制器与指令以及DOM隔离开。这是很重要的一点,因为它使控制器看不到它,从而大大改善了应用程序的测试过程。


13

$rootScope不管您在哪个控制器中,都可以全局使用,而$scope仅对当前控制器及其子级可用。


3

换句话说,我们可以看一下。$rootScope是全球的,$scope而是本地的。将Controller分配给页面时,$scope由于可以绑定到此控制器,因此可以在此处使用变量。但是,当我们想与其他控制器或服务共享其价值时,$rootScope就会被使用(**还有其他方法,我们可以共享价值,但在这种情况下,我们要使用$rootScope)。

关于如何定义这两个词的第二个问题是正确的。

最后有点偏离轨道,请$rootScope小心使用。与您使用全局变量的方式类似,调试起来很麻烦,并且您可能会意外地更改计时器内部某个地方的全局变量或使您的读数不正确的内容。



2

我建议您阅读有关作用域的官方深入Angular文档。从“范围层次结构”部分开始:

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

本质上,$ rootScope和$ scope都标识DOM的特定部分,其中

  • 进行角操作
  • 声明为$ rootScope或$ scope一部分的变量可用

属于$ rootScope的所有内容都可以在Angular应用程序中全局使用,而属于$ scope的所有内容都可以在该范围所应用的DOM部分中使用。

$ rootScope应用于DOM元素,该元素是Angular应用程序的根元素(因此名为$ rootScope)。将ng-app指令添加到DOM的元素时,这将成为$ rootScope在其中可用的DOM的根元素。换句话说,$ rootScope的属性等将在整个Angular应用程序中可用。

Angular $ scope(及其所有变量和操作)可用于应用程序中DOM的特定子集。具体来说,任何特定控制器的$ scope都可用于已应用该特定控制器的DOM部分(使用ng-controller指令)。请注意,尽管某些指令(例如ng-repeat)在应用于已应用控制器的DOM的一部分中时,可以创建主作用域的子作用域(在同一控制器内),但控制器不一定只包含一个作用域。

如果您在运行Angular应用程序时查看生成的HTML,则可以轻松查看哪些DOM元素“包含”了一个范围,因为Angular在已应用范围的任何元素(包括根元素)上添加了ng-scope类的应用程序(具有$ rootScope)。

顺便说一句,在$ scope和$ rootScope开头的$符号只是Angular中Angular保留的东西的标识符。

注意,通常不认为使用$ rootScope在模块和控制器之间共享变量等是最佳实践。JavaScript开发人员谈论通过在此处共享变量来避免全局范围的“污染”,因为稍后在其他地方使用相同名称的变量可能会发生冲突,而开发人员没有意识到已经在$ rootScope上声明了它。随着应用程序和开发团队规模的增加,此重要性也越来越高。理想情况下,$ rootScope仅包含常量或静态变量,这些常量或静态变量应在整个应用程序中始终保持一致。跨模块共享内容的一种更好的方法可能是使用服务和工厂,这是另一个主题!


2

两者都是Java脚本对象,其区别如下图所示。

在此处输入图片说明

NTB:
第一个有角度的应用程序尝试在$ scope中找到任何模型或函数的属性,如果在$ scope中找不到该属性,则它将在上层层次结构的父范围中进行搜索。如果仍未在较高层次结构中找到该属性,则angular尝试在$ rootscope中解析。


1

诸如John Papa的AngularJS样式指南之类的新样式建议我们完全不应该使用它$scope来保存当前页面的属性。相反,我们应该使用controllerAs with vm视图绑定到控制器对象本身的方法。然后在使用controllerAs语法时为此使用捕获变量。选择一个一致的变量名称,例如vm,代表ViewModel。

不过,您仍然需要$scope其观看功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.