在AngularJS中,自定義Directive過程中,有時用link和controller都能實現相同的功能。那麼,兩者有什麼區別呢?
使用link函式的Directive
頁面大致是:
<button id="addItem">Add Item</button>
<without-Controller datasource="customers" add="addCustomer"></without-Controller>
Directive方面:
(function(){ var withoutController = function(){ var tempalte = '<button id="addItem">Add Item</button><div></div>'; var link = function(scope, element, attrs){ //從scope中的datasource拿到資料來源 var items = angular.copy(scope.datasource), button = angular.element(document.getElementById('addItem')); button.on('click', addItem); render(); function addItem(){ var name = 'new customer'; //執行Directive中傳入的方法,帶引數 scope.$apply(function(){ scope.add()(name); }); items.push({ name: name }); render(); } function render(){ var html = '<ul>'; for(var i=0, len=item.length;i<len;i++){ html += '<li>' + items[i].name + '</li>' } html += '</ul>'; element.find('div').html(html); } }; reutrn { restrict: 'EA', scope: { datasource: '=', add: '&' }, link: link, template: template } }; angular.module('directiveModule') .directive('withoutController', withoutController); }());
使用controller的Directive
頁面大致是:
<with-controller datasource="customers" add="addCustomer"></with-controller>
Directive方面:
(function(){ var withController = function(){ var template = '<button ng-click="addItem()">Add Item</button><ul>' + '<li ng-repeat="item in items">{{::item.name}}</li></ul>', controller = ['$scope', function($scope){ init(); function init(){ $scope.items = angular.copy($scope.datasource); } $scope.addItem = function(){ var name = "customer new"; $scope.add()(name); $scope.items.push({ name: name }); } }]; return { restrict: 'EA', scope: { datasource: '=', add:'&' }, controller: controller, template:template } }; angular.module('directiveModule') .direcitve('withController', withController); }());
可見,link和controller的相同點在於裡面都可包含資料來源和操作。不同點在於:link能控制渲染html元素的過程,而controller不能,controller的模版寫死的,僅側重於提供資料來源和操作。
如果使用controllerAs,Directive大致是:
(function(){ var withController = function(){ var template = '<button ng-click="vm.addItem()">Add Item</button><ul>' + '<li ng-repeat="item in vm.items">{{::item.name}}</li></ul>', controller = function(){ var vm = this; init(); function init(){ vm.items = angular.copy($scope.datasource); } vm.addItem = function(){ var name = "customer new"; vm.add()(name); vm.items.push({ name: name }); } } return { restrict: 'EA', scope: { datasource: '=', add:'&' }, controller: controller, controllerAs: 'vm', bindToController:true, template:template } }; angular.module('directiveModule') .direcitve('withController', withController); }());
其中,controllerAs和bindToController屬性成對出現。