前言
在指令中存在controller和link屬性,對這二者心生有點疑問,於是找了資料學習下。
話題
首先我們來看看代碼再來分析分析。
第一次嘗試
頁面:
<custom-directive></custom-directive>
腳本:
angular .module('app',[]) .directive('customDirective', customDirective); function customDirective() { var directive = { restrict: 'EA', template: '<div>{{vm.test}}</div>', link: function(){}, controller: directiveController, controllerAs: 'vm' }; return directive; } function directiveController() { var vm = this; vm.test = "I'm from Controller"; }
【注】:基礎還是非常重要,頁面上為custom-directive,在腳本我寫成customdirective時死都沒出效果,改成customDirective才好使。
第二次嘗試
頁面自定義指令不變,我們就修改下腳本:
angular .module('app',[]) .directive('customDirective', customDirective); function customDirective() { var directive = { restrict: 'EA', template: '<div>{{test}}</div>', link: directiveLink }; return directive; } function directiveLink(scope,elem,attr) { scope.test = "I'm from Link"; }
到這里,我們不僅要開始思索:指令中的controller和link都可以實現同樣的效果,那在指令中放這兩個屬性干嘛?我們的代碼到底是放在controller還是link中?
我們首先來看看當二者一起使用時,呈現結果的順序即在編譯前后生成的順序。
controller和link編譯順序
我們將腳本進行修改如下:
angular .module('app',[]) .directive('customDirective', customDirective); function customDirective() { var directive = { restrict: 'EA', template: '<div>xpy0928{{test}}</div>', link: directiveLink, controller:directiveController }; return directive; } function directiveController($scope){ $scope.test = " from contrller cnblogs"; } function directiveLink(scope,elem,attr) { scope.test = scope.test + ",and from link cnblogs"; }
生成如下:
我們由此得出結論:編譯之前執行控制器(controller),編譯之后執行鏈接(link)。
但是我們還未從根本上解決問題,在controller和link應該放哪些代碼?我們接下來再看一個例子:
var app = angular.module('app',[]); app.directive('customDirective', customDirective); function customDirective() { var directive = { restrict: 'EA', template: '<child-directive><child-directive>', controller: function($scope, $element) { $element.find('span').text('hello cnblogs!'); } }; return directive; } app.directive("childDirective",childDirective); function childDirective() { var directive = { restrict: 'EA', template: '<h1>hello xpy0928</h1>', replace: true, link: function($scope, $element, attr) { $element.replaceWith(angular.element('<span>' + $element.text() + '</span>')); } } return directive; }
此時結果應該還是hello xpy0928還是hello cnblogs呢?我們看下結果:
我們再來將如上進行修改看看:
var app = angular.module('app',[]); app.directive('customDirective', customDirective); function customDirective() { var directive = { restrict: 'EA', template: '<child-directive><child-directive>', link: function(scope, el) { el.find('span').text('hello cnblogs!'); } }; return directive; } app.directive("childDirective",childDirective); function childDirective() { var directive = { restrict: 'EA', template: '<h1>hello xpy0928</h1>', replace: true, link: function($scope, $element, attr) { $element.replaceWith(angular.element('<span>' + $element.text() + '</span>')); } } return directive; }
為什么會出現如此情況?因為在controller函數中此時所有child-directive指令中的link函數還未運行所以此時替換無效。
由此我們可以基本得出在controller和link中應該寫什么代碼的結論:
(1)在controller寫業務邏輯(我們明白業務邏輯大部分是放在服務中),這里所說的業務邏輯乃是為呈現視圖之前而准備的數據或者是與其他指令進行數據交互而暴露這個api。
(2)在link中主要操作DOM。
總結
指令乃是AngularJS中比較重要的一塊,里面涉及到的東西也是非常之多,時不時的去往里面去灌東西,慢慢就會得心應手。