指令,简单的说就是一个在DOM上运行的函数,对元素进行扩展。
关于指令的方法directive()接受两个参数,name和function,下面我们来看一下指令长啥样:
angular.module('myApp',[])
.directive('myDirective', function(){
//一个指令定义对象
return {
//这里来写指令,和一些配置值
}
})
下面我们来看一指令的配置值: 1.restrict restrict是一个可选参数,传入的值为字符串,有4种可选参数A(属性),C(类名),E(元素),M(注释)。angularjs默认的restrict值为A。参数值也可以传入多个值。我们常用的为A和E。 【注】尽量避免注释方式,会与页面的注释相冲产生不必要的麻烦。 2.template和templateUrl template接受两种形式的参数,html文本或是一个返回html模板的函数。 templateUrl也接受两种形式的参数,html的文件路径和返回html文件路径的函数。 说白了,两个都是接受一个html,一个是直接的html模板,一个是把模板放到html文件而已。 有了以上两个简单的参数我们就可以写一个简单的directive了。
<div ng-app="app">
<div ng-controller="myController">
<div directive-test-attribute></div>
<directive-test-element></directive-test-element>
</div>
</div>
var app = angular.module("app", []);
app.controller("myController", function($scope){
})
app.directive("directiveTestAttribute", function() {
return {
restrict: 'A',
template: '<input type="text" />'
}
})
app.directive("directiveTestElement", function() {
return {
restrict: 'E',
template: '<input type="text" />'
}
})
3.replace replace接受布尔型的值,默认为false,使用时肯定是传入true了。false时,模板被当做元素插入调用的指令元素内部,如果为true的话则是替换指令元素。
4.scope scope默认值为false,直接继承父作用域。当传入值为true时,或从父作用域继承并创建一个新的自己的作用域。这样就是一个隔离的scope,不会影响到父作用域。 scope也可以传入一个对象,这样也会产生隔离域,可以选择性的继承父作用域的一些值,更具灵活性。 下面我们就来细致的了解一下对象,看代码:
<directive-test-element my-data="myData" name="name" change-name="changeName()"></directive-test-element>
app.directive("directiveTestElement", function() {
return {
restrict: 'E',
scope: {
myDate: '=',
name: '@',
changeName:'&'
},
template: '<div ng-click="changeName()">{{name}}</div>'
}
})
首先我们来了解一下“=”,“@”和“&”, “=”传进来的值还是双向绑定的,“@”传进来的值就是单向绑定的了。 “&”则是传入的函数。 这里看一下,页面上传值得属性都是“-”分割的,而指令里面则是写成驼峰形式的,这是angular规定的写法。就像directive定义也是驼峰形式,html上写则是“-”格式的。
【注】关于隔离域还是存在一些问题,就是当指令在ng-repeat中使用时会出现问题。不管怎么传值,都会是单向的。具体原因我认为是ng-repeat也有属于他自己的作用域,导致指令在repeat中继承的是父作用域是ng-repeat的。所以传入的值就成单向的了,在指令中改变变量的值不会影响到ctrl的值了。
关于如何解决这个问题,还没想到更好的方法,我是直接在link的属性里通过传入的scope找到它外层的ng-repeat的作用域再找外层ctrl的作用域,然后更改值,从而在directive中更改ctrl的值。
5.link 在指令中用link函数来创建操作DOM的指令。 函数有四个参数,分别是:
- scope 用来在指令内部注册监听器的作用域。
- element 代表实例元素,用来操作DOM。
- attrs 代表实例属性。
- controller 指令的控制器。
6.controller和controllerAs 指令可以创建自己的ctrl,controller属性接受一个controller的注入。 controllerAs参数用来设置控制器的别名,可以以次为名来发布控制器,这样我们就可以在view中直接引用控制器。
app.directive('myDirective', function() {
return {
controller: 'myController',
controllerAs: 'myCtrl',
template: '<div>{{myCtrl.name}}</div>'
}
})
app.controller('myController', function($scope){
$scope.name = 'directive可以直接在template中调用。';
})