var myapp=angular.module('myapp',[]) .controller('myctrl',['$scope', function ($scope) { $scope.color='red'; $scope.sayhello= function () { alert('hello'); }; }]) .directive('hello', function () { return{ restrict:'AECM', replace:true, template:'<button ng-click="sayhello()">click me</button>', scope:{ color:'=', sayhello:'&' }, link: function (scope,elements,attrs) { elements.bind('click', function () { elements.css('background-color','blue'); scope.$apply(function () { scope.color='pink'; }) }) } } }) <hello color="color" sayhello="sayhello()"></hello> <input type="text" ng-model="color"/>
这里我们也有两个地方需要注意:1、我们不仅需要在模板中使用ng-click指令,绑定上要调用的父scope中的方法,而且要在给当前元素添加一个属性,并且这个属性指向要调用的父scope的方法。2、指令scope的属性sayhello、当前元素的属性sayhello、模板绑定的事件方法名sayhello这三者要一致。那么这样我们就可以点击按钮,弹出一个对话框了。
6、transclude[boolean]属性,这个属性用来让我们规定指令是否可以包含任意内容
.directive('hello', function () { return{ restrict:'AECM', replace:true, transclude:true, scope:{}, template:'<div ng-transclude></div>', } }) <hello> hello <span>{{color}}</span> </hello>
当他的值为true的时候,这是页面上输出的值。当为false的时候,页面上将会是空白的。这里有一个地方需要注意,就是<span>{{color}}</span>,这里的color是父scope里的color。并不是指令里的scope的color属性。
7、compile[function]参数,该方法有两个参数element,attrs,第一个参数element指指令所在的元素,第二个attrs指元素上赋予的参数的标准化列表。这里我们也有个地方需要注意:compile 函数不能访问 scope,并且必须返回一个 link 函数。但是如果没有设置 compile 函数,你可以正常地配置 link 函数,(有了compile,就不能用link,link函数由compile返回)。
.directive('hello', function () { return{ restrict:'AECM', replace:true, translude:true, template:'<button ng-click="sayhello()">click me</button>', scope:{ color:'=', sayhello:'&' }, compile: function (element,attrs) { return function (scope,elements,attrs) { elements.bind('click', function () { elements.css('background-color','blue'); scope.$apply(function () { scope.color='pink'; }) }) }; } } })
现在让我们来点击这个按钮
我们发现,这里点击按钮之后发生的事情和前面用link属性的一样,这其实是没有多少差别的。
其实在大多数的情况下,我们只需要使用 link 函数。这是因为大部分的指令只需要考虑注册事件监听、监视模型、以及更新DOM等,这些都可以在 link 函数中完成。 但是对于像 ng-repeat 之类的指令,需要克隆和重复 DOM 元素多次,在 link 函数执行之前由 compile 函数来完成。那么为什么我们需要两个分开的函数来完成生成过程,为什么不能只使用一个?要回答好这个问题,我们需要理解指令在Angular中是如何被编译的!
8、指令是如何被编译的
当我们的angular应用引导启动的时候,angular将会使用$compile服务遍历DOM元素,在所有的指令都被识别之后,将会调用指令的compile方法,返回一个link函数,然后将这个link函数添加到稍后执行的 link 函数列表中,这个过程被称为编译阶段。像ng-repeat这样的指令,需要被重复克隆很多次,compile函数只在编译阶段被执行一次,并且复制这些模板,但是link 函数会针对每个被复制的实例被执行。所以分开处理,让我们在性能上有一定的提高(这句话有点不太理解,我是从别的地方copy过来的。原文在这里)。
9、controller[string or function]和require[string or string[]]参数,当我们想要允许其他的指令和你的指令发生交互时,我们就需要使用 controller 函数。当另一个指令想要交互时,它需要声明它对你的指令 controller 实例的引用(require)。
.directive('hello', function () { return{ scope:{}, require:'^he', compile: function (element,attrs) { return function (scope,elements,attrs,cntIns) { cntIns.fn() }; } } }) .directive('he', function () { return { restrict:'AE', scope:{}, controller: function ($scope, $compile, $http) { this.fn= function () { alert('hello'); }; } } }) <he> <hello color="color" sayhello="sayhello()"></hello> </he>
当页面加载完毕之后,会弹出一个对话框。