1.指令属性列表
.directive('directivename', function(){ return { restrict: String, replace: Boolean, transclude: Boolean, template: String or Template Func, templateUrl: String, priority: Number, terminal: Boolean, scope: Boolean or Obj, controller: String or Func, controllerAs: String, link: Func, compile: Func } })
2.属性使用
- restrict
取值:ACEM。A(属性,默认值),E(元素),C(类名),M(注释) - replace
取值:true、false。true(指令所在标签被替换),false(不替换,默认值) - transclude
取值:true、false。true(保留指令标签内部内容,ng-transclude存储原来内容),false(清空内部内容) - template
取值:string、Func。string(字符串拼接内容),func(方法retrun模版内容) - templateUrl
取值:string。外部模版地址 - priority、terminal
多个指令在同一元素内并且同时显示时会报错,所以它们组合使用。
priority(默认都相同,为0)根据数值从大到小排序优先级;
terminal(默认为false)为true时不显示比所在指令优先级低的指令
举个栗子
HTML
base.html
<div parent> ng-controller. <child1 child2></child1> </div>
templateUrl1.html
<h1>HELLO</h1>
script
angular.module('myApp', [])
.directive('parent', function() {
return {
replace: true,
transclude: true,
template: '<div>Hello directive.
<span ng-transclude></span></div>'
}
})
.directive('child1', function() {
return {
restrict: 'E', // 小写还不行
replace: false, // false可以不设置
templateUrl: 'templateUrl1.html', // 需要起个服务器
priority: 1, // 优先显示
terminal: true // 优先级低于1的不显示
}
})
.directive('child2', function() {
return {
restrict: 'AECM',
template: '<div>hide</div>'
}
})`
DOM结构
显示结果
- scope
取值:true、false、obj。false(共享父域,默认值),true(继承父域),obj(不继承父域,新建独立作用域)。
示例
template
<script type="text/html" id="s1"> <input type="text" ng-model="name"> {{ name }} </script>
HTML
<p> controller: <input type="text" ng-model="name"> {{ name }} </p> <p> <dt1></dt1> </p>
一、 false:共享作用域时,指令与控制器相互作用;
directive('dt1', function(){ return { restrict: 'E', template: function(){ return 'true:' + document.getElementById('s1').innerHTML; } } });
输入框相互影响
二、 true:继承父域时,可取到控制器内的元素,也会被影响,但不影响控制器
directive('dt1', function(){ return { restrict: 'E', scope: true, template: function(){ return 'true:' + document.getElementById('s1').innerHTML; } } });
true输入框变动不影响controller,可以得到controller内定义的值。true未改变前随着controller变动,改变后不被controller影响。
三、 obj:独立作用域
.controller('ctrl', function($scope){ $scope.name = 'baojian', $scope.show = function(cont) { console.log( cont ); }; });
directive('dt1', function(){ return { restrict: 'AE', scope: {}, template: function(){ return 'obj:' + document.getElementById('s1').innerHTML; } } });
1、 {},obj为{}时与controller之间无影响
2、 @,obj单向被controller影响,与true不同。也可以获取自定义属性的值。告诉myName取属性attrname中的值到新作用域,捋一捋这条线
directive scope = myName --> @attrname --> attrname --> {{name}} = controller scope
scope: { myName: '@attrname' }
注意是单向取值 {{ name }}
<dt attrname="{{name}}"></dt>
下面的情况@后面的字符可以省略
scope: { myName: '@myName' }
3、 =,obj与controller相互影响
directive scope = myName <--> @attrname <--> attrname <--> {{name}} = controller scope
scope: { myName: '=attrname' }
注意双向数据绑定直接用 name
<dt attrname="name"></dt>
下面的情况=后面的字符可以省略
scope: { myName: '=' }
4、 &,函数绑定
template: '<button ng-click="shw()">show</button>', scope: { shw: '&show' }
<div dt show="show(name)"></div>
- controller、link、compile
描述指令行为的3个参数。
1、controller
指令内部作用域的行为,一般绑定scope函数和变量在这里
controller: function($scope, $element){} // 指向匿名控制器
controller: "ctrl" // 指向控制器ctrl
2、link
操作DOM,绑定事件,改变样式等
link: function(scope, elems, attrs, ctrl) { /** scope可以取到作用域内的变量 *elems是jQuery对象 *ctrl 绑定的其他指令,有可能是数组。requre连接其他指令 */ elems.bind('click', function(){ }); elems.css('background-color','blue'); }
3、compile
scope不可用,使用compile时link不能用。返回link函数
compile: function(elem, attr) { return { pre: function (scope, elem, attr){}, post: function(scope, elem, attr){} } }
compile和link比较深入的大神分析 - controllerAs
给controller取别名,controller中可以用this代替$scope。$scope.$watch这种不能代替
controller: function() { this.name = 'baojian' }, controllerAs: 'bj', template: '<span>{{ bj.name }}</span>'
- require
请求其他指令的controller,两种匹配策略?。向上(父元素)查找controller,找不到报错;?查找指令有就返回,没有就返回undefined。请求后通过link的第4个参数传入使用
.directive('dt1', function(){
return {
controller: function(){
this.name = 'baojian'
}
}
});
.directive('dt2', function(){
return {
require: '?^dt1'
link: function(scope, elems, attrs, ctrl) {
if(ctrl) {
// 可以得到dt1的controller对象(ctrl=new dt1.controller())
console.log( ctrl.name );
}
}
}
});