Skip to content
1StepEngineer edited this page Aug 24, 2017 · 1 revision

指令

指令示例

<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 约束选项

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'

replace

  • true:替换匹配html
  • false: 在匹配html之内创建替换template

template | templateUrl

  • 若模板中包含多个dom元素,必须放在一个根dom元素上
  • templateUrl通过ajax请求html模板,因此本地开发需启动服务,否则造成CORS错误

scope (重点)

默认值 false

false:所有指令共享作用域,带来的问题是:一个指令作用域值发生变化,其他会一起发生变化

独立作用域 true

true:指令之间不再共享作用域;指令兄弟间进行独立;父子之间并未隔离

隔离作用域 {}

隔离作用域有3个绑定策略:@ = &

  • @ :绑定普通字符串
  • = :绑定的是外层controller里的数据,变成了变量
  • & :绑定父级函数,(重点:如何传参)

作用域优先级:directive中scope的设置 > directive中controller > directive外部controller

controller

针对自定义指令内部的控制器,自定义指令里面共享的数据可放在controller里面

link(重点)

放置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

内置指令

ng-repeat

  • $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
Clone this wiki locally