An in depth analysis of the concepts and relationships of $injector $rootScope and $scope in AngularJS

  • 2021-07-12 05:15:52
  • OfStack

This article illustrates the concepts and relationships of $injector, $rootScope and $scope in AngularJS. Share it for your reference, as follows:

$injector, $rootScope and $scope are important things in the AngularJS framework, and clarifying the relationship between them is very useful for us to learn and understand the angularJS framework later.

1. $injector is actually an IOC container, which contains many services (similar to bean in spring framework). Other codes can obtain the required services from injector through $injector. get ("serviceName"). Refer to this article for details: "Dependency injection instance analysis of AngularJS (using module and injector)"

2. scope is the scope in angularJS (in fact, the place where data is stored), which is very similar to the prototype chain of JavaScript. When searching, give priority to finding your own scope. If you don't find it, search up the scope chain until you reach the root scope rootScope.

3. $rootScope is created automatically when angularJS loads modules, and each module will only have one rootScope. When rootScope is created, it will be added to $injector as a service. That is, through $injector. get ("$rootScope"); The root scope of a module can be obtained. More precisely, $rootScope is created by ng, the core module of angularJS.

Example 1:


//  New 1 Modules 
var module = angular.module("app",[]);
// true Description $rootScope Is really included in the module's in the form of a service injector Medium 
var hasNgInjector = angular.injector(['app','ng']);
console.log("has $rootScope=" + hasNgInjector.has("$rootScope"));//true
//  Gets the corresponding module injector Object , Do not get ng Services in modules 
//  Not dependent on ng Module , Unable to get $rootScope Services 
var noNgInjector = angular.injector(['app']);
console.log("no $rootScope=" + noNgInjector.has("$rootScope"));//false
//  Get angular Core ng Module 
var ngInjector = angular.injector(['ng']);
console.log("ng $rootScope=" + ngInjector.has("$rootScope"));//true

The above code does show that $rootScope is indeed created by the core module ng and exists as a service in injector.

If the injector module is specified when the injector is created, the $rootScope service will be included in the injector; Otherwise, $rootScope is not included.

Example 2:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <script src="angular-1.2.25.js"></script>
    <script>
    var module = angular.module("app",[]);
    //  In the controller $injector, Is by angular Automatically created by the framework 
    function FirstController($scope,$injector,$rootScope)
    {
      $rootScope.name="aty";
    }
    // I created my own injector, Depend on app And ng Module 
    var myInjector = angular.injector(["app","ng"]);
    var rootScope = myInjector.get("$rootScope");
    alert(rootScope.name);//udefined
    </script>
  </head>
  <body ng-app="app">
    <div id="first" ng-controller="FirstController">
      <input type="text" ng-model="name">
      <br>
      {{name}}
    </div>
  </body>
</html>

angular. injector () can be called multiple times, each time returning the newly created injector object. Therefore, the myInjector created by ourselves and the $injector automatically created by angular are not the same object, so the resulting rootScope is not the same object. See the section on angular. injector () in another article, "Dependency Injection Example Analysis of AngularJS (Using module and injector)" for more details.

Example 3:


<!doctype html>
<html lang="en">
  <head>
    <script src="angular-1.2.25.js"></script>
    <script>
    function FirstController($scope,$injector,$rootScope)
    {
      // true
      console.log("scope parent :" + ($scope.$parent ==$rootScope));
    }
    </script>
  </head>
  <body ng-app>
    <div id="first" ng-controller="FirstController">
      <input type="text" ng-model="name">
      <br>
      {{name}}
    </div>
  </body>
</html>

The ng-controller directive creates a new $scope object for the existing DOM element and serves as a sub-scope of rootScope. $scope was created by $rootScope, and $scope is not included in $injector.

Example 4:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>scope()</title>
    <script src="jquery-1.11.1.js"></script>
    <script src="angular-1.2.25.js"></script>
    <script>
    // Remember rootScope Which is used to determine whether the cross-controller is equal 
    var first_rootScope = null;
    // Remember scope Which is used to determine whether the cross-controller is equal 
    var first_scope = null;
    // Remember injector Which is used to determine whether the cross-controller is equal 
    var first_injectot = null;
    //  No. 1 1 A angular Controller 
    function FirstController($scope,$injector,$rootScope)
    {
      $rootScope.name = "aty";
      first_rootScope = $rootScope;
      first_injectot = $injector;
      first_scope = $scope;
    }
    //  No. 1 2 A angular Controller , Mainly to test cross controller Hour injector And scope The performance of 
    function SecondController($scope,$injector,$rootScope)
    {
      console.log("first_rootScope==second_rootScope:" + (first_rootScope==$rootScope));//true
      console.log("first_injectot==second_injector:" + (first_injectot==$injector));//true
      console.log("first_scope==second_scope:" + (first_scope==$scope));//false
    }
    </script>
  </head>
  <body ng-app>
    <div id="first" ng-controller="FirstController">
      <input type="text" ng-model="name">
      <br>
      <div id="tips"></div>
    </div>
    <h2>outside of controller</h2>
    <br>
    <!-- Visit every 1 Applications ( Module ) Adj. rootScope-->
    {{$root.name}}
    <div id="noControllerDiv"/>
    <div ng-controller="SecondController">
    </div>
  </body>
</html>

ng-app defines one angular module, each of which has only one $rootScope, only one $injector, but can have multiple $scope.

To find out the relationship among $injector, $rootScope and $scope, let's look at two API provided by angular, one is scope () and one is injector (). The DOM object returned using angular. element () contains both methods to get the scope and injector associated with it.

Since the injector of each module is only 1, angular. element (). injector () directly returns the injector of the module in which the element resides.

angular. element (). scope () can get the scope or parent scope of the current element. If the current element has scope, return its own scope; If not, look in the direction of the father, and return rootScope if not found. That is, the scope nearest to the element in the scope chain is returned.


<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>scope()</title>
    <script src="jquery-1.11.1.js"></script>
    <script src="angular-1.2.25.js"></script>
    <script>
    function FirstController($scope,$injector,$rootScope)
    {
      // Get body Object 
      var domBody = document.getElementsByTagName('body')[0];
      //  Pass ng-app Where the instruction is located DOM Element acquisition rootScope
      var rtScope = angular.element(domBody).scope();
      // There is no new scope for the current element , Gets the parent scope that is rootScope
      var noScope = angular.element("#noControllerDiv").scope();
      // true
      console.log("rtScope==noScope:" + (rtScope==noScope));
      //ng-controller Element on which , Returned scope
      var scopeOnController = angular.element("#first").scope();
      // ng-controller Internal elements return the scope
      var inController = angular.element("#tips").scope();
      //true
      console.log("scopeOnController==inController:" + (scopeOnController==inController));
      // Verify through DOM Obtained scope Is it related to the injected $scope And $rootScope1 To 
      //true
      console.log("result1:" + (rtScope==$rootScope));
      //true
      console.log("result2:" + (inController==$scope));
    }
    </script>
  </head>
  <body ng-app>
    <div id="first" ng-controller="FirstController">
      <input type="text" ng-model="name">
      <br>
      <div id="tips"></div>
    </div>
    <h2>outside of controller</h2>
    <br>
    <!-- Visit every 1 Applications ( Module ) Adj. rootScope-->
    {{$root.name}}
    <div id="noControllerDiv"/>
  </body>
</html>

For more readers interested in AngularJS, please check out the topics on this site: "Introduction and Advanced Tutorial of AngularJS" and "Summary of AngularJS MVC Architecture"

I hope this paper is helpful to everyone's AngularJS programming.


Related articles: