談require選項以前,應該先說說controller選項,controller選項容許指令對其餘指令提供一個相似接口的功能,只要別的指令(甚至是本身)有須要,就能夠獲取該controller,將其做爲一個對象,並取得其中的全部內容。而require就是鏈接兩個指令的鎖鏈,它能夠選擇性地獲取指令中已經定義好的controller,並做爲link函數的第四個參數傳遞進去,link函數的四個參數分別爲scope,element,attr和someCtrl,最後一個就是經過require獲取的controller的名字,對於controller的名字,能夠在指令中用controllerAs選項進行定義,這是發佈控制器的關鍵.
html
具體如何獲取controller呢?require選項的值能夠分別用前綴?、^ 和?^進行修飾,也能夠不修飾。數組
若是不進行修飾,好比require:'thisDirective',那麼require只會在當前指令中查找控制器app
若是想要指向上游的指令,那麼就是用^進行修飾,好比require:'^parentDirective',若是沒有找到,那就會拋出一個錯誤。函數
若是使用?前綴,就意味着若是在當前指令沒有找到控制器,就將null做爲link的第四個參數;ui
那麼,若是將?和^結合起來,咱們就能夠既指定上游指令,又能夠在找不到時,不拋出嚴重的錯誤。this
如今問題來了,若是我想指定多於一個指令,那怎麼辦呢?這時,咱們能夠將須要的指令放進一個數組中,例如:require:['^?firstDirective','^?secondDirective','thisDirective'],這不正是依賴注入的形式嗎?但要注意一點,若是使用這種寫法的話,原先指令中發佈的控制器的名字,即controllerAs選項,就失去意義了。此時,咱們在link中調用這些指令的controller的方法變爲:先爲上邊的數組定義一個名字,接着根據其下標號來指定具體的某個指令。相似於:ctrlList[0]。spa
好,準備工做完畢,接下來經過一個大雜燴的實例來實踐require選項。我想實現的效果是,在主指令中,分別指定父級指令中的增長與減小的操做。rest
JS代碼:code
增長操做的指令:htm
.directive("add",function(){ return{ restrict:'ECMA', controller:function($scope){ $scope.count=0; this.addCount=function(){ $scope.$apply(function(){ $scope.count++; }) } } } })
減小操做的指令:
.directive("minor",function(){ return{ restrict:'ECAM', controller:function($scope){ this.reduceCount=function(){ $scope.$apply(function(){ $scope.count--; }) } } } })
主指令:
.directive("figure",function(){ return{ restrict:'ECMA', template:'<button id="add" class="btn btn-default">增長</button>'+ '<button id="minor" class="btn btn-danger">減小</button>'+ '<div>{{ figureCtrl.temp }}</div>', require:['?^add','?^minor'], controller:function(){ this.temp="這個屬性被隔離開,可經過controllerAs建立的動態對象調用"; }, controllerAs:'figureCtrl', link:function(scope,element,attrs,resultCtrl){ angular.element(document.querySelector('#minor')).on('click',resultCtrl[1].reduceCount); angular.element(document.querySelector('#add')).on('click',resultCtrl[0].addCount); } } })
HTML代碼:
<add minor class="col-md-2 col-md-offset-3"> <div >次數: {{ count }}</div> <figure></figure> </add>
運行結果以下圖:
注意點:
1.因爲add和minor指令都已被注入resultCtrl數組中,因此想調用它們的控制器中的方法,就可使用resultCtrl[i].fun()的方式;
2.更新count的值,但視圖是不會改變的,因此須要經過手動$apply()的方式來更新;
3.controllerAs其實是把controller建立爲一個對象,而且是隔離的。
大功告成!但仍是但願大神們能絕不吝嗇地對個人文章進行指點和糾正,謝謝!