Angularjs Source parsing 1:angular self-booting process

Source: Internet
Author: User

Once the Angularjs is loaded, there is an immediate function call, where the angular is initialized at the bottom of the source code. Code Show:

bindjquery ();p ublishexternalapi (angular); Jqlite (document). Ready (function() {     Angularinit (document, Bootstrap);});

The purpose of the Bindjquery method is to check if your main page refers to jquery, and if not, use the Jqlite, which is the angular itself, or the jquery you quoted.

    function Bindjquery () {        jQuery = window.jquery;     If the jquery library is loaded on the main page, jquery here will exist if          (jquery) {            = jquery; ...... else {= Jqlite ;                          If you do not reference the jquery library, use your own jqlite.        }         = Jqlite;      Assign the result to Angular.element    }

The function of the Publishexternalapi method is to bind some methods to the angular object first, then the module that initializes the angular core.

functionPublishexternalapi (angular) {extend (angular, {//Bind method to angular object' Bootstrap ': Bootstrap,

' Extend ': Extend,

' Element ': Jqlite,

' Injector ': Createinjector, ... }); Angularmodule=setupmoduleloader (window); This method binds the angular object to the window, then binds a function to the angular module property, and finally returns the function, which is a module loader, and the main function is to create and retrieve modules. The Angularmodule function here is the Angular.module function. Try{angularmodule (' Nglocale '); } Catch(e) {angularmodule (' Nglocale ', []). Provider (' $locale ', $LocaleProvider); Create a module named Nglocale and define a $localeprovider service provider named $locale on this module. The provider method here is to store the parameters in the method in the Invokequeue array so that they can be called later, which is easily known from the Setupmoduleloader method. } angularmodule (' ng ', [' Nglocale '], [' $provide ',//Create a module named Ng, which relies on the Nglocale module. functionNgmodule ($provide) {$provide. Provider ({$ $sanitizeUri: $ $SanitizeUriProvider}); $provide. Provider (' $compile ' , $CompileProvider). NG module, define a $compileprovider service provider named $compile directive ({A:htmlanchordirectiv E, input:inputdirective, textarea:inputdirective, F Orm:formdirective, Option:optiondirective, Ngbind:ngbinddirective, Ngclass:ngclassdirective, Ngcontroller:ngcontrollerdirective, Ngform:ngformdirective, Nghide:nghidedirective, ngif : Ngifdirective, Nginit:nginitdirective, Ngrepeat:ngrepeatdirective, Ngshow:ngshowdirective, Ngoptions:ngoptionsdirective, ng Transclude:ngtranscludedirective, Ngmodel:ngmodeldirective, Nglist:nglisTdirective, Ngchange:ngchangedirective, Required:requireddirective, Ngrequired:requireddirective, ngvalue:ngvaluedirective}); $provide. Provider ({//In the NG module, define a series of service provider $animate: $AnimateProvider, $controller: $ControllerProvider, $filter: $FilterProvider, $http: $HttpProvider, $location: $LocationProvider, $parse: $ParseProvider, $rootScope: $RootScopeProvider, $window: $WindowProvider}); } ]); }

Source code for the Setupmoduleloader method:

    functionSetupmoduleloader (window) {
     functionensure (obj, name, factory) {returnObj[name] | | (Obj[name] =Factory ()); } varAngular = ensure (window, ' angular '), Object); Setting Window.angular equals an empty object
returnEnsure (angular, ' module ',function() {//Set Angular.module to this module function and return this function. varModules = {}; return functionmodule (name, requires, CONFIGFN) {//When we pass var demo1 = angular.module (' demoApp ', []); When you create a module, it returns the Moduleinstanc E. And this Moduleinstance object has factory (), controller (), directive (), config (), run () and other methods can be called.
if(Requires &&Modules.hasownproperty (name)) {//If a module with the same name has been created, delete the previous module. A closure is used here, Because the modules object that is accessed is defined in an anonymous function in the outer layer each time a call to Angular.module is created, the variable inside is destroyed after the execution of the function, although the anonymous function is executed at the end, but because the intrinsic function module references this variable modules, So even if the outer anonymous function is executed, the modules variable defined inside it will not be destroyed.                    With closures, we can define a private variable modules, which can only be accessed through the specified method Angular.module, which cannot manipulate the private variable modules externally. Modules[name]=NULL; }                 returnEnsure (modules, name,function() {//modules[demoapp] = moduleinstance, and return this moduleinstance.                     varInvokequeue = [];                    varRunblocks = []; varConfig = invokelater (' $injector ', ' Invoke ');                    varModuleinstance ={//method of Module instanceRequires:requires,Provider:invokelater (' $provide ', ' provider '),Factory:invokelater (' $provide ', ' factory '),Service:invokelater (' $provide ', ' service '),Value:invokelater (' $provide ', ' value '),Constant:invokelater (' $provide ', ' constant ', ' unshift '),Animation:invokelater (' $animateProvider ', ' register '),Filter:invokelater (' $filterProvider ', ' register '),//When we create a filter from a module instance, we call the anonymous function () {invokequeue[' push ') returned by the Invokelater method ([$filterProvider, Register,   Arguments]);    return moduleinstance; }Controller:invokelater (' $controllerProvider ', ' register '),                  Directive:invokelater (' $compileProvider ', ' directive '),               Config:config,Run:function(block) {Runblocks.push (block); return  This; }                    };
            
if (CONFIGFN) {///when the call to the Angular.module method passes three parameters, the Config method is executed, and the third parameter is passed when the NG module is defined.
Config (CONFIGFN); The Config method is actually the return value after the Invokelater method executes. After execution here, it is also a push operation on the array invokequeue. When the NG module is created, Invokequeue = [[$injector, Invoke, [[$provide, Function Ngmodule () {}]]].
}
returnmoduleinstance; functionInvokelater (provider, method, InsertMethod) {return function() {Invokequeue[insertmethod|| ' Push '] ([Provider, method, arguments]); returnmoduleinstance; }; } }); }; }); }

Let's give an example of the above source code:

varDemo1 = Angular.module (' demoApp '), []);d Emo1.filter (' Reverse ',function() {When this method is called, the invokequeue["Push"] () method is called, and the module instance is returned for chained operation. For example: Demo1.filter (). Directive (). When the filter method of Demo1 is called, the invokequeue["push" is executed ([$filterProvider, register, ["Reverse", function () {}]]),    And this is just an array of push operations, i.e., Invokequeue = [[$filterProvider, Register, ["Reverse", function () {}]]]; return function(input, uppercase) {varout = "";  for(vari = 0; i < input.length; i++) { out= Input.charat (i) +Out ; }      if(uppercase) {out=out.touppercase (); }      returnOut ; }  });

After the Publishexternalapi method is finished, the next step is

Jqlite (document). When the Ready (function() {    ///document is loaded, execute the Angularinit method, which we often say: After the document is loaded, Angular just started out here.        Angularinit (document, Bootstrap);});
    functionAngularinit (element, bootstrap) {varelements =[element], appelement, module, names= [' Ng:app ', ' Ng-app ', ' X-ng-app ', ' Data-ng-app '],//angular has 4 ways to define angular applications on the page Ng_app_class_regexp=/\sng[:\-]app (: \s* ([\w\d_]+);?)? \s/; functionAppend (Element) {element&&Elements.push (Element); } forEach (Names,function(name) {Names[name]=true;            Append (document.getElementById (name)); Name= Name.replace (': ', ' \ \: ')); if(Element.queryselectorall) {ForEach (Element.queryselectorall ('. ' +name), append); ForEach (Element.queryselectorall ('. ' + name + ' \ \: '), append); ForEach (Element.queryselectorall (' [' + name + '] '), append);    }        }); For 4 definitions, get the element node defined as the angular app on the page, ForEach (elements,function(Element) {if(!appelement) {//appelement is defined only oncevarClassName = ' + Element.classname + '; varMatch =ng_app_class_regexp.exec (className); if(Match) {appelement=element; Module= (Match[2] | | "). Replace (/\s+/g, ', ')); } Else{ForEach (element.attributes,function(attr) {if(!appelement &&Names[attr.name]) {appelement=element; Module=Attr.value;                }                    });    }            }        });        The elements that define the angular application, that is, the element that is written on the page with Ng-app (4 ways defined), is defined as appelement. if(appelement) {bootstrap (appelement, module?[Module]: []);        If there is an element on the page that defines the angular app, it starts. }    }
    functionbootstrap (element, modules) {varDobootstrap =function() {//define a Function element=jqlite (Element); if(Element.injector ()) {//If the angular application of this element has been started, an error is thrownvarTag = (Element[0] = = = document)? ' Document ': Startingtag (Element); ThrowNgminerr (' BTSTRPD ', "App already bootstrapped with this Element ' {0} '", tag); } Modules= Modules | | []; Modules.unshift ([' $provide ',function($provide) {$provide. Value (' $rootElement ', Element);            }]); Modules.unshift (' Ng '); Here, we assume that the Ng-app element is defined on the page, without adding anything superfluous.            So here's the modules=["ng", ["$provide", function ($provide) {}]]. varInjector =createinjector (modules);            This method is very important, it takes our angular application needs to initialize the module array into the load, and creates a registrar instance object, and finally returns the Registrar instance object. Injector.invoke ([' $rootScope ', ' $rootElement ', ' $compile ', ' $injector ', ' $animate ',//Invoking the Invoke method of the Registrar instance objectfunction(scope, element, compile, injector, animate) {scope. $apply (function() {Element.data (' $injector ', injector);                        Compile (Element) (scope);                });            }]            ); returnInjector;        }; varNg_defer_bootstrap =/^ng_defer_bootstrap!/; if(Window &&!)ng_defer_bootstrap.test (Window.name))            {//If Window.name does not start with ng_defer_bootstrap!, enter the IF statement to execute the method defined above. returnDobootstrap (); } window.name= Window.name.replace (Ng_defer_bootstrap, "); Angular.resumebootstrap=function(extramodules) {ForEach (Extramodules,function(module) {Modules.push (module);            });        Dobootstrap ();    }; }

When the above invoke method executes, it will call the compile method, which will be used to compile the instance, and then compile the application by compiling the elements, the core of the compilation is to generate instructions corresponding to the link function.

Come on!

Angularjs Source parsing 1:angular self-booting process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.