Angular學習筆記-angular是如何執行的

angular執行圖:
圖片描述
jquery啓動:
js dom元素綁定相應的事件,當dom監聽到相應的事件,這時就開始執行註冊的這個事件.
angularjs執行:
首先,綁定jquery,判斷是否引入jquery,若是沒有引入jquery,本身會實現一個jqlit。
其次,publishExternalApi
2,publishExternalApi 在啓動angular以前首要準備好service,directives...,首先在angular上註冊forEach,bind方法
好比:
2.1須要備案,可以是angular能方便找到你,yourName就是檢索
[]就是依賴css

var APP = angular.module('yourName',[],configFn)
angular.module()建立、獲取、註冊angular中的模塊
傳遞參數不止一個,表明新建模塊;空數組表明該模塊不依賴其餘模塊  
  var createModule = angular.module("myModule", []);  
    只有一個參數(模塊名),表明獲取模塊,若是模塊不存在,angular框架會拋異常  
   var getModule = angular.module("myModule");  
   getModule ==createModule
configFn就是你出生的時候能夠作些初始化之類的動做,好比娃娃大叫...

2.2,出生以後能夠有不少的技能,好比會angular編程,會java...,而後這些技能都須要取個名字...html

var APP = angular.module('yourName',[],configFn)
app.controller(xx)
factory()...
service()...
...
angular.module(name, [requires], [configFn]);
name:字符串類型,表明模塊的名稱;
requires:字符串的數組,表明該模塊依賴的其餘模塊列表,若是不依賴其餘模塊,用空數組便可;
configFn:用來對該模塊進行一些配置。

2.3,有了技能以後要讓人知道,因此要暴露你的技能讓別人來用.java

如在services.js裏面setupModuleLoader在angular上註冊module,controller等api最後返回的是:
return(moduleInstance=(_invokeQueue:[],_runBlocks:[],controller factory service...))

2.4,有了技能,別人也已經知道了,而後也準備好了讓別人調用了,首先別人須要遍歷你的技能,把全部的技能都列在一個list invokeQueue上jquery

moduleInstance={_invokeQueue _runBlock}

2.5,技能都掌握在一我的的手裏,他的名字叫ng,下面就是ng的備案:
angularModule('ng',['ngLocal'],['$provide',function ngModule($provide){//ngLocal是ng本身不會的技能,因此要依賴於別人
$provide.provider('$compile',$compileProvider).directive({//compile服務是ng本身的技能angularjs

A:htmlDirective,
 input:inputDirective,
 ...

}).directive(ngAttributeAliasDirectives).directive(ngEventDirectives);編程

$provide.provider({
   $anchorScroll:$AnchorScrollProvider,
   $animate:$AnimateProvider,
   $browser:$BrowserProvider
 })

}])
3,angularInit
全部的東西都準備好了,如今開始啓動:2種方法啓動
1),ng-app
2),跳過第一步直接 doBootstrap(element,[module])
3.1在解析html的時候,不少directives的技能都是有ng這我的掌握,因此首先要召喚出ng,另外還須要註冊$rootElement,這個由無名氏掌握(放在匿名的空間裏)bootstrap

modules=[
'ng',['$provide',function($provide){$provide.value('$rootElement',element);

}],'myApp'
]
3.2 全部的技能都調集起來了如今開始決鬥了,首先調用createInjecter,這裏咱們定義2個技能的集合:api

createInjecter(modules)
//providerCache存放全部人的技能,無論名字,只管技能
 providerCache:{$provider,$injector}
//若是調用過了就放在這裏,方便下次尋找,若是須要新的技能就去大庫裏尋找
instanceCache:{$injector}

3.3 遍歷每一個人的invokeQueue數組

.loadModules
 if:string 遍歷,檢索出module,遍歷invokeQueue,將其技能放在定義好的庫裏面
 var invokeArgs = invokeQueue[i],
 provider = providerInjecter.get(invokeArgs[0])
 provider[invokeArgs[1]].apply(provider,invokeArgs[2]);
 if:function或Array, 直接providerInjector.invoke
 return runBlocks

3.4 遍歷全部人的技能 遍歷runBlocks
forEach(runBlocks){app

instanceInjector.invoke

}
3.5 編譯全部的dom compile dom
injector.invoke(['$rootScope'...])

demo 執行順序 4,2,3,1
   var app = angular.module('demo',[])
   app.controller('test',[function(){//放在providerCach裏,等compile服務執行以後才執行
     console.log('step1')
   }])
  
   app.config('test',[function($provide){//其次是config
     console.log('step2')
   }])
  
   app.run(function(){
     console.log('step3')
   })
  
   angular.element(document).ready(function(){//首先是dom ready
    console.log('step4')
    angular.bootstrap(angular.element(document),['demo'])
   })

4,angularjs源碼解析
angular源碼是一個自執行函數,當js被加載完以後,當即執行。除了最後一行.

在angular的源碼中,這段代碼不是自執行函數。
!window.angular.$$csp() && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');

代碼開始執行:

if (window.angular.bootstrap) {//判斷angularjs是否是已經啓動,若是已經啓動了就報錯WARNING: Tried to load angular more than once.
    //AngularJS is already loaded, so we can return here...
    console.log('WARNING: Tried to load angular more than once.');
    return;
  }

  //try to bind to jquery now so that one can write jqLite(document).ready()
  //but we will rebind on bootstrap again.
  bindJQuery();//對jquery庫進行綁定

  publishExternalAPI(angular);//將angular的api擴展到angular全局函數

  jqLite(document).ready(function() {
    angularInit(document, bootstrap);//啓動angular,默認從document開始啓動
  });

咱們在寫angularjs的時候,老是要定義全局的angular函數,好比:
var app = angular.module('app',[])
那麼這個angular的全局函數從哪裏來的呢?

/** @name angular */
    angular           = window.angular || (window.angular = {}),
    //若是window.angular有值就返回--> angular = window.angular
    //若是沒有值 window.angular = {} --> angular = {} 是一個空對象。

angular 是如何調用module函數呢?
angular.module
function publishExternalAPI

extend(angular, {//extend是一個工具函數,複製的做用
    'bootstrap': bootstrap,
    'copy': copy,
    'extend': extend,
    'merge': merge,
    'equals': equals,
    'element': jqLite,
    'forEach': forEach,
    'injector': createInjector,
    'noop': noop,
    'bind': bind,
    'toJson': toJson,
    'fromJson': fromJson,
    'identity': identity,
    'isUndefined': isUndefined,
    'isDefined': isDefined,
    'isString': isString,
    'isFunction': isFunction,
    'isObject': isObject,
    'isNumber': isNumber,
    'isElement': isElement,
    'isArray': isArray,
    'version': version,
    'isDate': isDate,
    'lowercase': lowercase,
    'uppercase': uppercase,
    'callbacks': {counter: 0},
    'getTestability': getTestability,
    '$$minErr': minErr,
    '$$csp': csp,
    'reloadWithDebugInfo': reloadWithDebugInfo
  });
相關文章
相關標籤/搜索