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

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
⚠️ **GitHub.com Fallback** ⚠️