溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Angularjs中啟動過程的示例分析

發(fā)布時間:2021-08-20 11:00:32 來源:億速云 閱讀:138 作者:小新 欄目:web開發(fā)

這篇文章主要介紹Angularjs中啟動過程的示例分析,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

啟動過程(v1.3.9)

步驟一

用自執(zhí)行函數(shù)的形式讓整個代碼在加載完成之后立即執(zhí)行

in angular.js Line6

(function(window, document, undefined)

在window上暴露一個唯一的全局對象angular,Line250 

angular = window.angular || (window.angular = {})

 獲得其它工具模塊 Line 2129

 function publishExternalAPI(angular) {
  extend(angular, {
   'bootstrap': bootstrap,
   'copy': copy,
   'extend': extend,
   'equals': equals,
   'element': jqLite,
   'forEach': forEach,
   'injector': createInjector,
   'noop': noop,
   'bind': bind,
   .....

我們來看看angular全局對象都有什么東西

Angularjs中啟動過程的示例分析

接著,我們使用全局對象中的isFunction 來遍歷一下angular全局對象上的屬性,函數(shù)

 var counter = 0;
 for (var p in angular) {
   counter++;
   if (angular.isFunction(angular[p])) {
     console.log("function->" + p);
   } else {
     console.log("property-->" + p + "-->" + angular[p]);
   }
 }
 console.log(counter);

有兩個property,其它都是function

Angularjs中啟動過程的示例分析

我們再來看看injector里都有什么

 /**
  * angular.injector();
  */
 var injector = angular.injector();
 console.log(injector);

一共有5個方法

annotate:分析函數(shù)簽名(不要new的原因)

Angularjs中啟動過程的示例分析

步驟二

檢查是不是多次導(dǎo)入Angular:window.angular.bootstrap(通過檢查指定的元素上是否已經(jīng)存在injector進行判斷)

in angular.js line 26041

   if (window.angular.bootstrap) {
    //AngularJS is already loaded, so we can return here...
    console.log('WARNING: Tried to load angular more than once.');
    return;
   }

angular的三種啟動方式

自動啟動

Angular會自動的找到ng-app,將它作為啟動點,自動啟動

 <!DOCTYPE html>
 <html ng-app="myModule">

 <head>
   <title>New Page</title>
   <meta charset="utf-8" />
   <script type="text/javascript" src="../../vendor/bower_components/angular/angular.min.js"></script>
   <script type="text/javascript" src="./02.boot1.js"></script>
 </head>

 <body>
   <div ng-controller="MyCtrl">
     <span>{{Name}}</span>
   </div>
 </body>
 </html>

js

 var myModule = angular.module("myModule", []);
 myModule.controller('MyCtrl', ['$scope',
   function($scope) {
     $scope.Name = "Puppet";
   }
 ]);

手動啟動

在沒有ng-app的情況下,只需要在js中添加一段注冊代碼即可

<body>
   <div ng-controller="MyCtrl">
     <span>{{Name}}</span>
   </div>
 </body>

js

 var myModule = angular.module("myModule", []);
 myModule.controller('MyCtrl', ['$scope',
   function($scope) {
     $scope.Name = "Puppet";
   }
 ]);

 /**
  * 這里要用ready函數(shù)等待文檔初始化完成
  */
 angular.element(document).ready(function() {
   angular.bootstrap(document, ['myModule']);
 });

多個ng-app

ng中,angular的ng-app是無法嵌套使用的,在不嵌套的情況下有多個ng-app,他默認(rèn)只會啟動第一個ng-app,第二個第三個需要手動啟動(注意,不要手動啟動第一個,雖然可以運行,但會拋異常)

<body>
   <div id="app1" ng-app="myModule1">
     <div ng-controller="MyCtrl">
       <span>{{Name}}</span>
     </div>
   </div>
   <div id="app2" ng-app="myModule2">
     <div ng-controller="MyCtrl">
       <span>{{Name}}</span>
     </div>
   </div>
 </body>

js

 /**
  * 第一個APP
  * @type {[type]}
  */
 var myModule1 = angular.module("myModule1", []);
 myModule1.controller('MyCtrl', ['$scope',
   function($scope) {
     $scope.Name = "Puppet";
   }
 ]);
 // angular.element(document).ready(function() {
 //   angular.bootstrap(app1, ['MyModule1']);
 // });

 /**
  * 第二個APP
  * @type {[type]}
  */
 var myModule2 = angular.module("myModule2", []);
 myModule2.controller('MyCtrl', ['$scope',
   function($scope) {
     $scope.Name = "Vincent";
   }
 ]);
 angular.element(document).ready(function() {
   angular.bootstrap(app2, ['myModule2']);
 });

步驟三

嘗試綁定jQuery,如果發(fā)現(xiàn)導(dǎo)入了jQuery ,則使用導(dǎo)入的jQuery,否則,使用Angular自己封裝的JQLite

in angular.js line 1521:

bindJQuery();

in angular.js line 1534:

 jQuery = window.jQuery;

if (jQuery && jQuery.fn.on) {
  jqLite = jQuery;
  extend(jQuery.fn, {
   scope: JQLitePrototype.scope,
   isolateScope: JQLitePrototype.isolateScope,
   controller: JQLitePrototype.controller,
   injector: JQLitePrototype.injector,
   inheritedData: JQLitePrototype.inheritedData
  });

測試

<html ng-app="myModule">


<body>
  <div>
    <div ng-controller="MyCtrl">
      <span>{{Name}}</span>
    </div>
  </div>
</body>

</html>

js

var myModule = angular.module("myModule", []);
myModule.controller('MyCtrl', ['$scope',
  function($scope) {
    $scope.Name = "Puppet";
  }
]);

查看執(zhí)行流程

Angularjs中啟動過程的示例分析

步驟四

發(fā)布ng提供的API

in angular.js line 2162 : publishExternalAPI(angular);

//構(gòu)建模塊加載器
angularModule = setupModuleLoader(window);
 try {
  angularModule('ngLocale');
 } catch (e) {
  angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
 }

模塊加載器的實現(xiàn)原理

in angular.js function setupModuleLoader(window)

function setupModuleLoader(window) {

 var $injectorMinErr = minErr('$injector');
 var ngMinErr = minErr('ng');

 function ensure(obj, name, factory){
 return obj[name] || (obj[name] = factory());
 }
 var angular = ensure(window, 'angular', Object);
 // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
 angular.$$minErr= angular.$ $minErr || minErr;
 //把module方法放到angular的全局對象上,ensure就是一個屬性拷貝的過程
return ensure(angular, 'module', function(){
  //模塊緩存
  var modules = {};
}

把工具函數(shù)給載到模塊里

return function module(name, requires, configFn) {
......
}

查看模塊里所包含的內(nèi)容

<!DOCTYPE html>
<html ng-app="myModule">

</html>

JS

/**
 * 定義模塊
 */
var myModule = angular.module("myModule", []);

/**
 * 從debug的過程可以看到,angular中的“模塊”只是一個閉包空間(或者叫命名空間)
 * 所有模塊都被注冊在modules這個對象上
 */
console.log(myModule);

查看控制臺

Angularjs中啟動過程的示例分析

構(gòu)建內(nèi)置模塊ng

in angular.js line 2169 publishExternalAPI(angular)

 angularModule('ng', ['ngLocale'], ['$provide',
  function ngModule($provide) {
   // $ $sanitizeUriProvider needs to be before $compileProvider as it is used by it.
   $provide.provider({
    $ $sanitizeUri: $$SanitizeUriProvider
   });
   $provide.provider('$compile', $CompileProvider).
    directive({
      a: htmlAnchorDirective,
      input: inputDirective,
      ......

加載了所有內(nèi)置的directive,provider.注冊ng內(nèi)核Provider:兩個最重要的$parser $rootScope

總結(jié)

  1. 工具函數(shù)拷貝到angular全局對象上;

  2. 調(diào)用setupModuleLoader方法創(chuàng)建模塊定義和加載工具(掛在全局對象window.angular上);

  3. 構(gòu)建內(nèi)置模塊ng;

  4. 創(chuàng)建ng內(nèi)置的directive和provider;

  5. 兩個重要的provider:$parse 和 $rootScope;

步驟五

初始化Angular - 查找Ng-app

 jqLite(document).ready(function() {
  angularInit(document, bootstrap);
 });

bootstrap

創(chuàng)建injector,拉起內(nèi)核和啟動模塊,調(diào)用compile服務(wù)(一個ng-app只有一個injector)

in angular.js line 1415

function bootstrap(element, modules, config){
....
}

以上是“Angularjs中啟動過程的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI