本文例子所使用版本爲 v1.3.9javascript
用自執行函數的形式讓整個代碼在加載完成以後當即執行html
inangular.js
Line6java
javascript(function(window, document, undefined)
在window上暴露一個惟一的全局對象angular,Line250angularjs
/** @name angular */ //若是window.angular已經有值了,就把原有的賦值給前面angular,若是沒有則用window.angular空對象賦值給angular angular = window.angular || (window.angular = {}), angularModule, uid = 0;
得到其它工具模塊 Line 2129bootstrap
function publishExternalAPI(angular) { extend(angular, { 'bootstrap': bootstrap, 'copy': copy, 'extend': extend, 'equals': equals, 'element': jqLite, 'forEach': forEach, 'injector': createInjector, 'noop': noop, 'bind': bind, .....
咱們來看看angular全局對象都有什麼東西緩存
接着,咱們使用全局對象中的isFunction
來遍歷一下angular全局對象上的屬性,函數閉包
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,其它都是functionapp
咱們再來看看injector裏都有什麼ide
/** * angular.injector(); */ var injector = angular.injector(); console.log(injector);
一共有5個方法
annotate:分析函數簽名(不要new的緣由)函數
檢查是否是屢次導入Angular:window.angular.bootstrap(經過檢查指定的元素上是否已經存在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; }
方式 1:自動啓動
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"; } ]);
方式 2:手動啓動
在沒有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函數等待文檔初始化完成 */ angular.element(document).ready(function() { angular.bootstrap(document, ['myModule']); });
方式 3:多個ng-app
ng中,angular的ng-app是沒法嵌套使用的,在不嵌套的狀況下有多個ng-app,他默認只會啓動第一個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,若是發現導入了jQuery ,則使用導入的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"; } ]);
查看執行流程
in angular.js
line 2162 : publishExternalAPI(angular);
//構建模塊加載器 angularModule = setupModuleLoader(window); try { angularModule('ngLocale'); } catch (e) { angularModule('ngLocale', []).provider('$locale', $LocaleProvider); }
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 = {}; }
javascriptreturn function module(name, requires, configFn) { ...... }
查看模塊裏所包含的內容
<!DOCTYPE html> <html ng-app="myModule"> </html>
JS
/** * 定義模塊 */ var myModule = angular.module("myModule", []); /** * 從debug的過程能夠看到,angular中的「模塊」只是一個閉包空間(或者叫命名空間) * 全部模塊都被註冊在modules這個對象上 */ console.log(myModule);
查看控制檯
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, ......
加載了全部內置的directive,provider.註冊ng內核Provider:兩個最重要的$parser
和 $rootScope
$parse
和 $rootScope
;javascriptjqLite(document).ready(function() { angularInit(document, bootstrap); });
建立injector,拉起內核和啓動模塊,調用compile服務 (一個ng-app只有一個injector)
in angular.js
line 1415
function bootstrap(element, modules, config){ .... }
本文原載於@Puppet 原創學習筆記,如需轉載請附上 原文連接>>