anagularJs指令的controller,link,compile有什么不同
/directives.js增加exampleDirective phonecatDirectives.directive('exampleDirective', function() { return { restrict: 'E', template: '<p>Hello {{number}}!</p>', controller: function($scope, $element){ $scope.number = $scope.number + "22222 "; }, link: function(scope, el, attr) { scope.number = scope.number + "33333 "; }, compile: function(element, attributes) { return { pre: function preLink(scope, element, attributes) { scope.number = scope.number + "44444 "; }, post: function postLink(scope, element, attributes) { scope.number = scope.number + "55555 "; } }; } } }); //controller.js添加 dtControllers.controller('directive2',['$scope', function($scope) { $scope.number = '1111 '; } ]); //html <body ng-app="phonecatApp"> <div ng-controller="directive2"> <example-directive></example-directive> </div> </body>
运行结果:
Hello 1111 22222 44444 55555 !
由结果可以看出来,controller先运行,compile后运行,link不运行 (link就是compile中的postLink)。
将上例中的compile注释掉
// compile: function(element, attributes) { // return { // pre: function preLink(scope, element, attributes) { // scope.number = scope.number + "44444 "; // }, // post: function postLink(scope, element, attributes) { // scope.number = scope.number + "55555 "; // } // }; // }
运行结果:
Hello 1111 22222 33333 !
由结果可以看出来,controller先运行,link后运行,link和compile不兼容。
<div ng-controller="ctrl1"> <superman weight length speed>superman</superman> <superman weight >weight</superman> </div> <script type="text/javascript"> angular.module('myMoudle',[]) .controller('ctrl1', ['$scope', function($scope){ }]) .directive("superman", function(){ return { restrict : "E", scope : {}, controller : function($scope){ $scope.abilities = []; this.addWeight = function(){ $scope.abilities.push("Weight"); } this.addSpeed = function(){ $scope.abilities.push("Speed"); } this.addLength = function(){ $scope.abilities.push("Length"); } }, link : function(scope, element){ element.bind("mouseenter", function(){ console.log(scope.abilities); }) } } }) .directive("weight", function(){ return { restrict : "A", require : "superman", link : function(scope, element, attrs, superman){ superman.addWeight(); } } }) .directive("speed", function(){ return { restrict : "A", require : "superman", link : function(scope, element, attrs, superman){ superman.addWeight(); } } }) .directive("length", function(){ return { restrict : "A", require : "superman", link : function(scope, element, attrs, superman){ superman.addLength(); } } }) </script>
controller : 指令的controller中放一些公共部分,通过require让多个指令共享controller中的数据。
require : ^ 允许从父类开始查找 require:"^superman"; ? 如果找不到不抛出异常。
scope : {} 创建独立作用域,没有原型继承。= or =attr “Isolate”作用域的属性与父作用域的属性进行双向绑定,任何一方的修改均影响到对方,这是最常用的方式;@ or @attr “Isolate”作用域的属性与父作用域的属性进行单向绑定,即“Isolate”作用域只能读取父作用域的值,并且该值永远的String类型; & or &attr “Isolate”作用域把父作用域的属性包装成一个函数,从而以函数的方式读写父作用域的属性,包装方法是$parse;
link : 主要做一些dom操作;
link和controller的相同点在于里面都可包含数据源和操作。不同点在于:link能控制渲染html元素的过程,而controller不能,controller的模版写死的,仅侧重于提供数据源和操作。
使用link函数的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:
(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); }());