自定义指令的各种属性详解

【一】 自定义指令的两种方式

           1. 通过 module.directive(name,directiveFactory) 定义 , 如:        

         (function() {
           angular.module('starter')
             .directive('myCustomer', function() {
                return {
                   restrict: 'E',
                   templateUrl: 'directiveTest/my-customer.html'
            };
           })
          })()

           2. 注入 $compileProvider ,通过 $compileProvide.directive() 定义 , 如:

       var myApp = angular.module('myApp', [], ['$compileProvider',function ($compileProvider) {
         $compileProvider.directive('customTags',function(){
          return {
            restrict:'ECAM',
            template:'
custom-tags-html
', replace:false } }); }])

【二】 restrict 、 template 、 replace、templateUrl属性

      var myApp = angular.module('myApp', [], ['$compileProvider',function ($compileProvider) {
       // 如果指令的名字为xxx-yyy 在设置指令的名字时应为 xxxYyy 驼峰式命名法
       $compileProvider.directive('customTags',function(){
         return {
            restrict:'ECAM',
            template:'
custom-tags-html
',             replace:false,             // templateUrl :加载模板所要使用的URL             //replace :如果为true 则替换指令所在的元素,如果为false 或者不指定,则把当前指令追加到所在元素的内部             //restrict :指令在模板中的使用方式             //可以4种风格任意组合,如果忽略restrict,默认为A             // E : 风格为 元素  (作为标签名)      使用方式: 1212             // C: 风格为 样式类                   使用方式:
            // A : 风格为 属性                    使用方式:
            // M : 风格为 注释             // 注意:当有两个directive的时候 只能有一个template,否则会报错         }     }); }])
【三】transclude、priority、terminal 属性

           priority : 设置指令在模板中的执行顺序,顺序是相对于其他元素上的指令而言,默认为0,从大到小的顺序一次执行

           terminal : 是否以当前指令的权重为结束界限。如果这个值设置为true,则节点中权重小于当前指令的其他指令不会被执行。相同权重的会执行 

    .directive('customTags', function () {
        return {
            restrict: 'ECAM',
            template:'
新数据
', replace: true, transclude:true //transclude:为true时,指令元素中的原来的子节点移动到一个新模板内部(移动到的位置通过ng-transclude确定) //priority 设置优先级 } }) .directive('customTags2', function () { return { restrict: 'ECAM', template:'
2
', replace: true, priority:0 } }) .directive('customTags3', function () { return { restrict: 'ECAM', template:'
3
', replace: true, priority: 1, // terminal 为true 时 priority 小于当前指令的priority的directive 都不会执行 terminal:true } })
【四】 compile 和 link 属性

Angularjs 指令编译三个阶段

1.标准浏览器API转化
     将html 转化成dom ,所以自定义的html 标签必须符合html 的格式
2.Angular compile
     搜索匹配 directive ,按照priority排序,并执行directive上的compile 方法
3.Angular link
      执行directive上的link 方法,进行 scope绑定及事件绑定
   link 函数负责在模型和视图之间进行动态关联

     .directive('customTags',function(){
        return {
            restrict : 'ECAM',
            template : '
{{user.name}}
', replace : true, compile:function(tElement,tAttrs,transclude){ // 1.编译阶段...主要可以进行DOM 结构的操作 // tElement.append(angular.element('
{{user.name}}{{user.count}}
')); console.log('customTags compile 编译阶段...'); return { //2.Link 包括 pre 和 post 主要可以用在添加事件的绑定和scope绑定 // 2.1.1表示在编译阶段之后,指令连接到子元素之前运行 pre:function preLink(scope,iElement,iAttrs,controller){ console.log('customTags preLink..') }, // 2.1.2表示在所有子元素指令都连接之后才运行 post:function postLink(scope,iElement,iAttrs,controller){ iElement.on('click',function(){ //需要用 $apply触发一次 脏检查 scope.$apply(function(){ scope.user.name = 'click after'; scope.user.count = ++i; }); }) console.log('customTags all child directive link..') } } // 也可以直接返回 postLink // return function postction(scope,iElement,iAttrs,controller){ // console.log('compile return fun'); // } }, // 此link表示的就是 postLink // link:function postction(scope,iElement,iAttrs,controller){ // iElement.on('click',function(){ // scope.$apply(function(){ // scope.user.name = 'click after'; // scope.user.count = ++i; // // 进行一次 脏检查 // }); // }) // } } })
【五】controller 、controllerAs 和 require 属性 
     .directive('bookList', function() {
       return {
        restrict: 'ECAM',
        // controller 会暴露一个API ,利用这个API 可以在多个指令之间通过依赖注入进行通信
        controller: function($scope) {
            $scope.books = [{
                name: 'php'
            }, {
                name: 'javascript'
            }, {
                name: 'java'
            }];


            this.addBook = function() {


                $scope.$apply(function() {
                    $scope.books.push({
                        name: 'Angularjs'
                    })
                });
            }
        },
        controllerAs: 'bookListController',//controllerAs:给上面的controller 起个别名
        template: '
  • {{book.name}}
',         replace: true     } }) .directive('bookAdd', function() {     return {         restrict: 'ECAM',         require: '^bookList',         //require 可以将其他指令传递给自己 ,如此可以去调用其他的指令的函数和修改其他指令的字段,实现不同指令之间的通信         // (没有前缀)如果没有前缀,指令将会在自身所提供的控制器中进行查找,如果没有找到任何控制器就抛出一个错误。         // ? 如果在当前指令中没有找到所需要的控制器,会将null作为传给link函数的第四个参数。         // ^ 如果添加了^前缀,指令会在上游的指令链中查找require参数所指定的控制器。         // ?^ 将前面两个选项的行为组合起来,我们可选择地加载需要的指令并在父指令链中进行查找。         template: '',         replace: true,         link: function(scope, iElement, iAttrs, bookListController) {             //点击调用第一个指令的addBook函数             iElement.on('click', bookListController.addBook);         }     } })
【六】 scope 属性

           scope : 为当前指令创建一个新的作用域
           false : 继承父元素的作用域
           true : 创建一个新的作用域

          参数:
              &:作用域把父作用域的属性包装成一个函数,从而以函数的方式读写父作用域的属性
              =: 作用域的属性与父作用域的属性进行双向绑定,任何一方的修改均会影响到对方
              @:只能读取父作用域里的值单项绑定

           

    .directive('bookList', function () {
        return {
            restrict: 'ECAM',
            controller: function ($scope) {
                $scope.books = $scope.a();
                $scope.books = $scope.b;
                $scope.b.push({name:'nodejs'});
                console.log($scope.c);
            },
            // 创建一个有继承链的独立作用域
            // scope:true,

            // 当scope 为对象的时独立的作用域候也会创建一个
            scope:{
                // 将父元素books封装成一个a函数(&:作用域把父作用域的属性包装成一个函数,从而以函数的方式读写父作用域的属性)
                a:'&books'
                // 双向绑定 b = parentBooks属性对应的父作用域的表达式(=:作用域的属性与父作用域的属性进行双向绑定,
                //     任何一方的修改均会影响到对方)
                b:'=parentBooks'

                // 只能使用简单数据类型的方法,不能用对象(@ :只能读取父作用域里的值单向绑定)
                c:'@parentTitle'
            },
            controllerAs:'bookListController',
            template: '
  • {{book.name}}
', replace:true } }) .controller('firstController', ['$scope', function ($scope) { console.log($scope); $scope.books = [ { name: 'php' }, { name: 'javascript' }, { name: 'java' } ]; $scope.title = '张三'; }]);

       注意:html 文件中的属性写法要与指令中定义的相匹配。以上面的为例,html中:

 

你可能感兴趣的:(【,AngularJS,+ionic,】)