摘要:因為在里面是基于原型進行繼承的。事實上注入后,即提供了一個,可以在這個上面綁定屬性和方法。當(dāng)使用語法的時候,事實上是綁定到了的對象上面。注意這個地方執(zhí)行順序是從子元素開始再到父元素的。即在執(zhí)行階段前確保執(zhí)行完畢。
Controller As
angular .module("app", []) .controller("DemoController", DemoController); function DemoController() { this.name = "XL"; this.sayName = function() { return this.name; } }{{vm.name}}
在js部分書寫控制器的時候,更像是在寫構(gòu)造函數(shù),然后在view層實例化一個ViewModule。那么在view里面可以直接調(diào)用掛載在這個vm上的屬性和方法。
這樣的寫法的好處就是避免在嵌套的controller里面使用$parent去獲取父controller里面的方法或值。因為在angular里面scope是基于原型進行繼承的。
{{name}}angular .module("app") .controller("parentController", parentController) .controller("childController", childController); //都使用的推斷式注入 function parentController($scope) { $scope.name = "XL"; } function childController($scope) { $scope.name = "xl"; }{{name}}
最后在視圖里面輸出"XL", "xl"。如果我要獲取的是父控制器里面的屬性值,那么我只能$scope.$parent去獲取,嵌套的controller多了怎么辦- -,使用controller as可以有效的避免這個問題.
如果使用這種controller as的寫法的話,盡量避免在controller里面使用$scope,除非遇到$emit,$broadcase,$on, $watch。
function SomeController($scope, $log) { var vm = this; vm.title = "Some Title"; $scope.$watch("vm.title", function(current, original) { $log("vm.title was %s", original); $log("vm.title is now %s", current); }); }this vs $scope
angular .module("app", []) .controller("parentController", parentController); function parentController($scope) { this.sayName = function() { console.log("this"); } }
結(jié)果:
點擊BtnA后能輸出"this",
點擊BtnB后不輸出任何東西。
事實上:
當(dāng)書寫Controller的時候,即在寫controller constructor,使用controller as語法,當(dāng)在view里面實例化controller后(vm),this便指向這個實例化vm,然后就可以在view里面調(diào)用vm所擁有的屬性和方法。在本例中即vm所擁有的sayName()方法
如果
function parentController($scope) { this.sayName = function() { console.log("this"); } $scope.sayName = function() { console.log("$scope"); } }
在controller constructor里面定義$scope.sayName方法,那么點擊BtnB的時候可以輸出$scope。
事實上:
注入$scope后,即提供了一個model,可以在這個model上面綁定屬性和方法。那么在view里面聲明的controller里面可以訪問到。
綜上,在this上面掛載的方法其實是在controller constructor上面掛載的方法,必須要通過controller實例去訪問。在$scope上面掛載的方法是在模型上面掛載的,因為在directive的pre-link階段(見下面的compile vs link)是將$scope綁定到DOM上,因此可以直接在view層訪問綁定在$scope的方法。
除此之外,this和$scope另外一個區(qū)別就是指向的問題:
log "this" and $scope
- parent scopelog "this" and $scope
- child scope
然后僅僅在parentController上面掛載方法:
$scope.logThisAndScope = function() { console.log(this, $scope); }
首先因為controller嵌套同時是在$scope上面掛載方法,因此父元素和子元素點擊都會輸出this和$scope的內(nèi)容,在這個實例當(dāng)中this的指向是不同的,一個是parentController另外一個是childController,$scope的指向是一樣的,同時指向的是綁定在id為parentBox的DOM內(nèi)的$scope。
The problem with controllerAs in Directives當(dāng)使用controllerAs語法的時候, controller scope事實上是綁定到了controller的this對象上面。但是在平時我們書寫directive的時候會創(chuàng)建獨立的作用域。
app.directive("someDirective", function() { return { scope: { oneWay: "@", twoWay: "=", expr: "&" } } })
接下來我們創(chuàng)建一個擁有獨立作用域,有自己的控制器的directive。
app.directive("someDirective", function() { return { scope: {}, controller: function() { this.name = "Pascal"; }, controllerAs: "ctrl", template: "{{ctrl.name}}" } })
但是,如果這個name屬性是一個可以和父作用域共享的呢?當(dāng)然我們立馬想到的是
app.directive("someDirective", function() { return { scope: { name: "=" }, .... } })
如果外部的name屬性發(fā)生變化并不會立即反應(yīng)到內(nèi)部的controller的this對象上。在1.2版本里面處理這種情況就是使用$scope服務(wù)上掛載的$watch方法去監(jiān)聽name屬性的變化。
app.directive("someDirective", function() { return { scope: { name: "=" }, controller: function($scope) { this.name = "Pascal"; $scope.$watch("name", function(newValue){ this.name = newValue; }.bind(this)); //這個地方要注意this的指向 } } })bindToController
1.3版本里面directive出現(xiàn)了一個新的配置對象bindToController,顧名思義綁定到controller上面,當(dāng)directive使用獨立作用域以及controllerAs語法的時候,而且bindToController這個值被設(shè)置為true的時候,這個組件的屬性都被綁定到controller上了而不是scope上面。
這意味著,當(dāng)controller被實例化后,獨立作用域上綁定屬性的初始值都可以通過this對象來訪問到,未來這個屬性的值發(fā)生變化后都能被檢測的到。
app.directive("someDirective", function () { return { scope: { name: "=" }, controller: function () { this.name = "Pascal"; }, controllerAs: "ctrl", bindToController: true, template: "{{ctrl.name}}" }; });
1.4版本的語法升級:
在1.3版本bindToController為boolen值,在1.4版本中為一個對象,即如果想將獨立作用域上的值綁定到controller上面,可以直接在bindToController這個對象上進行配置。
app.directive("someDirective", function () { return { scope: {}, bindToController: { someObject: "=", someString: "@", someExpr: "&" }, controller: function () { this.name = "Pascal"; }, controllerAs: "ctrl", template: "complie vs link{{ctrl.name}}{{ctrl.someObject}}" }; }); //如果父作用域里面的someObject屬性發(fā)生變化,會隨時反應(yīng)到這個directive的template里面。
Angularjs在處理directive時,取決于自身的compile和link參數(shù)定義的規(guī)則:
當(dāng)定義directive的時候同時定義了complie,pre-link,post-link3個參數(shù)的時候
Hello {{XL}} Hello {{Sugar}}
var app = angular.module("app", []); function createDirective(name) { return function() { return { restrict: "E", compile: function(tElem, tAttrs) { console.log(name + ": complie"); }, return { pre: function(scope, tElem, iAttrs) { console.log(name + ": pre link"); }, post: function(scope, tElem, iAttrs) { console.log(name + ": post link"); } } } } } app.directive("levelOne", createDirective("levelOne")); app.directive("levelTwo", createDirective("levelTwo")); app.directive("levelThree", createDirective("levelThree"))
結(jié)果:
angularjs一開始compile所有原生指令和自定義指令,complile階段還沒有綁定scope.link階段分為pre-link和post-link階段。
從結(jié)果看來compile階段和pre-link階段的順序一樣,但是post-link執(zhí)行順序正好相反。
修改代碼:
function createDirective(name) { return function() { return { restrict: "E", compile: function(tElem, tAttrs) { console.log(name + ": complie =>" + tElem.html()); }, return { pre: function(scope, iElem, iAttrs) { console.log(name + ": pre link =>" + iElem.html()); }, post: function(scope, iElem, iAttrs) { console.log(name + ": post link =>" + iElem.html()); } } } } }
結(jié)果:
現(xiàn)在再看下輸出的信息,特別是在pre-link階段,雖然和compile一樣輸出元素的順序是一樣的,但是元素中出現(xiàn)了屬性class="ng-binding",事實上在compile階段DOM元素仍然是最初html標(biāo)記所創(chuàng)建的DOM元素,它是模板元素(template element)的實例元素(instance element).pre-link階段提供一個scope給這個實體,這個實體可以是全新的scope,繼承的scope或者是孤立的scope,取決于directive定義的scope屬性。
post-link階段:當(dāng)實例元素初始化完成(compile階段)和綁定scope(pre-link階段)完成后就可以進行post-link(DOM)操作。注意這個地方執(zhí)行順序是從子元素開始再到父元素的。即在level-one執(zhí)行post-link階段前確保level-two.level-three執(zhí)行完畢。
compile階段: /* * @param tElem - 模板元素 * @param tAttr - 模板元素的屬性 */ compile: function(tElem, tAttrs) { } pre-link階段 /* * @param scope - 連接于此的實例的scope * @param iElem - 實例元素 * @param iAttr - 實例元素的屬性 */ function (scope, iElem, iAttr) { } post-link階段 /* * @param scope - 連接于此實例的scope * @param iElem - 實例元素 * @param iAttr - 實例元素的屬性 */ function (scope, iElem, iAttr) { }where to use compile or link?
之前的寫法都是直接用link,默認(rèn)進行了compile和pre-link的階段,在post-link里面就可以直接使用綁定在實例上的scope,ele,attrs。
如果在你的程序里面不需要使用scope,不需要$watch其他的值,僅僅提供模板實例的話,可以直接使用compile。這個時候你是不能對DOM有任何操作的。
除此之外,如果你不需要實例元iElem,那么也可以不用link函數(shù)。
但當(dāng)你同時書寫compile和link函數(shù)(pre-link或者post-link)的時候,一定要在compile函數(shù)里面返回link函數(shù),因為如果compile被定義的時候link屬性被忽略了。
參考資料bindToController
thisAndScope
the difference between compile and link
angularjs-style
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78327.html
摘要:使用開發(fā),很重要的一步是需要開發(fā)自定義的指令。接下來分幾個步驟記錄如何開發(fā)一個自定義的指令。對這個元素及其子元素進行變形之類的操作是安全的。鏈接函數(shù)鏈接函數(shù)負(fù)責(zé)注冊事件和更新。說明和是指令的關(guān)鍵部分,留在下一章中詳細(xì)討論。 使用Angularjs開發(fā),很重要的一步是需要開發(fā)自定義的指令(custom directives)。接下來分幾個步驟記錄如何開發(fā)一個自定義的指令。 目錄: 指令...
摘要:基于原型的繼承性視圖存在嵌套的時候,內(nèi)層的是可以繼承到外層的數(shù)據(jù)的。這者的區(qū)別就是在中繼承了中的作用域。通過監(jiān)聽某個的是否發(fā)生變化來觸發(fā)相應(yīng)的。第三個屬性值,當(dāng)為規(guī)定的是比較對象的值,而不是引用。這樣可以非常好的將一些可服用的代碼抽離出來。 scope基于原型的繼承性 視圖存在嵌套的時候,內(nèi)層的controller是可以繼承到外層的controller數(shù)據(jù)的。 scope在angula...
摘要:雖然這些東西都是非常棒的,但是它們都不是實現(xiàn)延遲加載所必需的東西。我們通過的配置對象中的屬性就可以實現(xiàn)延遲加載。單元測試的技巧把改成是全局依賴并不意味著你應(yīng)該從控制器中刪除它。因為在單元測試中,你只會加載這一個控制器而非整個應(yīng)用模塊。 原文鏈接:http://michalzalecki.com/lazy-load-angularjs-with-webpack/ 隨著你的單頁應(yīng)用擴大,...
摘要:異步加載各個組件就很有必要。在這里我就以為框架來進行異步加載說明。而為了將服務(wù)進行異步加載我們不能用普通的或者。而需要調(diào)用或者如果采用進行編譯打包的話就需要的支持,這樣可以對進行拆分打包,達到異步加載的目的。 ui-route相比于angularjs的原生視圖路由更好地支持了路由嵌套,狀態(tài)轉(zhuǎn)移等等。隨著視圖不斷增加,打包的js體積也會越來越大,比如我在應(yīng)用里面用到了wangeditor...
摘要:本文針對的讀者具備性能優(yōu)化的相關(guān)知識雅虎條性能優(yōu)化原則高性能網(wǎng)站建設(shè)指南等擁有實戰(zhàn)經(jīng)驗。這種機制能減少瀏覽器次數(shù),從而提高性能。僅會檢查該和它的子,當(dāng)你確定當(dāng)前操作僅影響它們時,用可以稍微提升性能。 搬運自: http://atian25.github.io/2014/05/09/angular-performace/ 不知不覺,在項目中用angular已經(jīng)半年多了,踩了很多坑...
閱讀 2893·2021-09-28 09:36
閱讀 3647·2021-09-27 13:59
閱讀 2497·2021-08-31 09:44
閱讀 2285·2019-08-30 15:54
閱讀 2359·2019-08-30 15:44
閱讀 1192·2019-08-30 13:45
閱讀 1231·2019-08-29 18:38
閱讀 1219·2019-08-29 18:37