指令 - Mirror198829/AngularJs1 GitHub Wiki
<nl-tabs tabs-data="tabsData" show-name="showName()" title="tabsDemo"></nl-tabs>
app.directive("nlTabs",function(){
return{
restrict:"AE",
templateUrl:'src/directive/nl-tab/nl-tabs.html',
replace:true,
scope:{
title:"@", //绑定普通字符串
tabsData:"=", //绑定外部控制器相应变量值
showName:"&" //绑定外部控制器的函数
},
controller::['$scope',function($scope){
$scope.title="我是指令内部控制器数据"
}],
link:function(scope,ele,attrs){
ele.delegate(".nl-tabs_item","click",function(){
var num=0;
$(this).addClass("active").siblings('.nl-tabs_item').removeClass("active");
num=ele.find('.nl-tabs_item').index($(this));
ele.find(".nl-tabs_content").removeClass("active").eq(num).addClass("active");
})
}
}
})
- js中指令的名称是驼峰式,如:blgMenu
- HTML中模板使用blg-meun形式(规则:html和css采用连字符分隔命名,不区分大小写,在js中命名变量使用驼峰是正确的规范,ng的html编译器遇到左侧形式,会转成对应驼峰式。)
- 指令名称唯一
- 不能使用ng开头前缀,因ng内置指令已经占用
restrict共有4个选项,为了指明ng在HTML模板中如何触发指令
- A: 只匹配属性名
<div blg-menu></div>
- E: 只匹配元素名
<blg-menu></blg-menu>
- C: 只匹配类名
<div class="blg-menu"></div>
- M: 只匹配注释
<!--directive:blg-menu-->
通常设置为 restrict:'AE'
- true:替换匹配html
- false: 在匹配html之内创建替换template
- 若模板中包含多个dom元素,必须放在一个根dom元素上
- templateUrl通过ajax请求html模板,因此本地开发需启动服务,否则造成CORS错误
false:所有指令共享作用域,带来的问题是:一个指令作用域值发生变化,其他会一起发生变化
true:指令之间不再共享作用域;指令兄弟间进行独立;父子之间并未隔离
隔离作用域有3个绑定策略:@ = &
- @ :绑定普通字符串
- = :绑定的是外层controller里的数据,变成了变量
- & :绑定父级函数,(重点:如何传参)
作用域优先级:directive中scope的设置 > directive中controller > directive外部controller
针对自定义指令内部的控制器,自定义指令里面共享的数据可放在controller里面
放置dom操作的地方
- $apply(),$apply(function(){}):$apply()方法可以在angular框架之外执行angular JS的表达式,例如:DOM事件、setTimeout、XHR或其他第三方的库
- link中使用jquery写dom操作时不要写成
$(".nl-tabs_item").removeClass('active')
(忌),非常容易造成一个页面多个相同指令引入后,获取dom数不符合预期
<div ng-controller="testCtrl">
<h1>用于测试执行顺序</h1>
<nl-test></nl-test>
</div>
function logTest(text){
console.log(text);
debugger;
}
app.controller('testCtrl',function($scope){
logTest('外部testCtrl');
});
app.directive('nlTest',function(){
logTest('指令初始化');
return{
restrict:"AE",
template:'<div>{{name}}</div>',
controller:['$scope',function($scope){
$scope.name="指令模板";
logTest("指令内controller")
}],
link:function(scope,ele,attrs){
logTest("指令内link")
}
}
})
执行结果顺序为:
- template内含ng指令:指令初始化 => template dom展示 => 外部testCtrl => 指令内controller => 指令内link => template ng指令调用
- template不含ng指令:指令初始化 => template dom展示 => 外部testCtrl => 指令内controller => 指令内link
- $first :循环第一个
- ng-click/dbclick ng-mousedown/up ng-mouseenter/leave ng-mousemove/over/out ng-keydown/up/press ng-focus/blur ng-submit
- ng-selected
- ng-change
- ng-copy
- ng-cut
- ng-paste