摘要:前言由于在博客系統(tǒng)的開發(fā)中和近期工作中的前端框架主要使用因此在這里記錄學(xué)習(xí)和使用的過程中遇到的一些需要記錄的點(diǎn)。執(zhí)行過程弄清楚的執(zhí)行過程是很重要的,這樣你才能在正確的時(shí)機(jī)做正確的事。至此,的執(zhí)行過程也就告一段落了。
前言
由于在博客系統(tǒng)的開發(fā)中和近期工作中的前端框架主要使用 AngularJS ,因此在這里記錄學(xué)習(xí)和使用 AngularJS 的過程中遇到的一些需要記錄的點(diǎn)。特別說明,本文并非教程。
執(zhí)行過程弄清楚 AngularJS 的執(zhí)行過程是很重要的,這樣你才能在正確的時(shí)機(jī)做正確的事。在這點(diǎn)上我就犯過錯(cuò)誤,話不多說,直接上代碼:
var app = angular.module("app", ["ngRoute"]); app.config([ "$routeProvider", "$http", "$q", function ($routeProvider, $http, $q) { $routeProvider .when("/", { template: "123", resolve: { auth: function () { // do stuff } } }); } ]);
報(bào)錯(cuò)啦!!!上面的代碼在啟動(dòng)階段就會(huì)報(bào)下圖所示的錯(cuò)誤:
乍一看都不知道錯(cuò)在哪里,經(jīng)過分析才知道,module.config 方法是在 on module loading,即模塊加載過程中執(zhí)行的,此時(shí) $http 和 $q 等服務(wù)都還沒有創(chuàng)建成功,不能當(dāng)做依賴項(xiàng)注入到 module.config 方法中。
回到主題,AngularJS 框架的執(zhí)行過程大致如下所示:
配合源碼會(huì)理解的更清楚:
bindJQuery(); publishExternalAPI(angular); jqLite(document).ready(function() { angularInit(document, bootstrap); });
具體代碼可以到源碼中查看,這里簡要說明一下:
bindJQuery() 嘗試綁定jQuery對象,如果沒有則采用內(nèi)置的jqLite。
publishExternalAPI(angular) 初始化 angular 環(huán)境,為 angular 對象注冊 module,forEach,extend 等方法。
關(guān)于 module 方法,在此要說明一下:
angular.module("myApp") 只傳一個(gè)參數(shù),為getter操作,返回 moduleInstance 對象,而 angular.module("myApp",[]) 傳入兩個(gè)參數(shù),為setter操作,也返回 moduleInstance 對象
var moduleInstance = { // Private state _invokeQueue: invokeQueue, _runBlocks: runBlocks, requires: requires, name: name, 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"), controller: invokeLater("$controllerProvider", "register"), directive: invokeLater("$compileProvider", "directive"), config: config, run: function(block) { runBlocks.push(block); return this; } }
angularInit(document, bootstrap) 方法內(nèi)容如下:
function angularInit(element, bootstrap) { var elements = [element], appElement, module, names = ["ng:app", "ng-app", "x-ng-app", "data-ng-app"], NG_APP_CLASS_REGEXP = /sng[:-]app(:s*([wd_]+);?)?s/; function append(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); } }); forEach(elements, function(element) { if (!appElement) { var className = " " + element.className + " "; var match = 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; } }); } } }); if (appElement) { bootstrap(appElement, module ? [module] : []); } }
遍歷names,通過 document.getElementById(name) 或者是 querySelectorAll(name) 檢索到 element 后存入 elements 數(shù)組中,最后獲取到 appElement 以及module。
舉個(gè)例子:我們一般會(huì)在文檔開始的html標(biāo)簽上寫 ng-app="myApp",通過以上方法,我們最后可以得到名為 myApp 的 module,后調(diào)用 bootstrap(appElement,[module]);
bootstrap 中需要重點(diǎn)關(guān)注 doBootstrap 方法:
var doBootstrap = function() { element = jqLite(element); if (element.injector()) { var tag = (element[0] === document) ? "document" : startingTag(element); throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element "{0}"", tag); } //通過上面分析我們知道此時(shí) modules 暫時(shí)是這樣的: modules = ["myApp"]; modules = modules || []; //添加$provide這個(gè)數(shù)組 modules.unshift(["$provide", function($provide) { $provide.value("$rootElement", element); }]); //添加 ng這個(gè) module ,注意:1857行 我們注冊過ng 這個(gè)module,并在1854行 我們注冊過 它的依賴模塊"ngLocale", //angularModule("ngLocale", []).provider("$locale", $LocaleProvider); 我們注冊過ngLocale這個(gè)module modules.unshift("ng"); //調(diào)用createInjector(module) 此時(shí):module為: //["ng",["$provide",function(){}],"myApp"] 兩個(gè)type為string,一個(gè)為array var injector = createInjector(modules); injector.invoke(["$rootScope", "$rootElement", "$compile", "$injector", "$animate", function(scope, element, compile, injector, animate) { scope.$apply(function() { element.data("$injector", injector); compile(element)(scope); }); }] ); return injector; };
最后通過 $apply 將作用域轉(zhuǎn)入 angular 作用域,所謂angular作用域是指:angular采用dirity-check方式進(jìn)行檢測,達(dá)到雙向綁定。
再利用 compile 函數(shù)編譯整個(gè)頁面文檔,識別出 directive,按照優(yōu)先級排序,執(zhí)行他們的 compilie 函數(shù),最后返回 link function 的結(jié)合,通過 scope 與模板連接起來,形成一個(gè)即時(shí),雙向綁定。
至此,AngularJS 的執(zhí)行過程也就告一段落了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81415.html
摘要:回調(diào)說白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)和,下面的方法請求成功執(zhí)行,失敗執(zhí)行異步異步的原理我看了網(wǎng)上的一些博客和例子,大都以定時(shí)任務(wù)為例子說明,但具體的原理我還是不太 回調(diào) 說白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)success和error,下...
摘要:回調(diào)說白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)和,下面的方法請求成功執(zhí)行,失敗執(zhí)行異步異步的原理我看了網(wǎng)上的一些博客和例子,大都以定時(shí)任務(wù)為例子說明,但具體的原理我還是不太 回調(diào) 說白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)success和error,下...
摘要:引言指令可以說是的核心,而其開發(fā)也是比較困難的,本文主要介紹指令的一些參數(shù)和的綁定策略。指令執(zhí)行的優(yōu)先級,用于多個(gè)指令同時(shí)作用于同一個(gè)元素時(shí)。改變父會(huì)影響指令,而改變指令不會(huì)影響父。在父和指令之間建立雙向綁定。 引言 指令(Directive)可以說是 AngularJS 的核心,而其開發(fā)也是比較困難的,本文主要介紹指令的一些參數(shù)和scope的綁定策略。 參數(shù) 從 AngularJS ...
摘要:點(diǎn)擊我啊當(dāng)屬性為空時(shí),點(diǎn)擊的時(shí)候頁面不會(huì)刷新了,我們再也不需要這樣寫了點(diǎn)擊我啊一般和指令結(jié)合使用點(diǎn)擊我啊你點(diǎn)擊我了一般和標(biāo)簽結(jié)合使用。使用了就就可以避免出現(xiàn)這種問題。如果鏈接中有表達(dá)式,就使用代替 a 點(diǎn)擊我啊 當(dāng)href屬性為空時(shí),點(diǎn)擊的時(shí)候頁面不會(huì)刷新了,我們再也不需要這樣寫了 點(diǎn)擊我啊 一般和ng-click指令結(jié)合使用 #html 點(diǎn)擊我啊 #scr...
摘要:自定義指令中有很多內(nèi)置指令,一般都是以開頭的比如等等。本文介紹的自定義指令的用法。該參數(shù)的意思是替換指令的內(nèi)容,更改上面的例子。將屬性綁定到父控制器的域中學(xué)習(xí)概念多指令中的參數(shù)中增加了的值和的點(diǎn)擊函數(shù)。 自定義指令 angularjs中有很多內(nèi)置指令,一般都是以ng開頭的;比如:ng-app,ng-click,ng-repeat等等。本文介紹angularjs的自定義指令的用法。 指令...
閱讀 1395·2021-09-26 09:55
閱讀 1927·2019-08-30 12:45
閱讀 1071·2019-08-29 11:20
閱讀 3564·2019-08-26 11:33
閱讀 3432·2019-08-26 10:55
閱讀 1700·2019-08-23 17:54
閱讀 2393·2019-08-23 15:55
閱讀 2352·2019-08-23 14:23