美文网首页我爱编程
angular自定义指令

angular自定义指令

作者: LabRaDor2079 | 来源:发表于2017-08-14 22:34 被阅读0次
    var app = angular.module("app",[]);
    //第一个参数:指令的名称,使用驼峰命名
    //第二个参数:回调函数,回调函数内部返回对象
    app.directive("hiHello",function () {
            return {
            //执行的代码,参数,写在这里
            }
    });
    

    directive的参数

    restrict : String

    设置自定义指令的html格式

    restrict的取值表
    | E| C | M | A |
    |:---------------:|:------:|
    | element | attribute | class | 注释 |

    <body>
        <!-- 1 : 使用指令的第一种方式 -->
        <hi-hello>若其中有内容,则被替换掉</hi-hello>
        <!-- 2: 属性 -->
        <div hi-hello></div>
        <!-- 3:类名 -->
        <div class="hi-hello"></div>
        <!-- 4:注释 指令名后面保留一个空格 -->
        <!-- directive:hi-hello -->
    </body>
    <script type="text/javascript">
        var app = angular.module("app",[]);
        app.directive("hiHello",function () {
                return {
                    /* ECMA
                     * E : element
                     * A : attribute
                     * C : class
                     * M : 注释
                    */
    
                   restrict:"EACM",//可以组合使用,顺序不限,得大写 (默认值为EA)
                    // 如果使用M,必须得配合使用 replace(替换)
                    replace:true,//默认值为false  表示是否替换当前元素
    
                    //设置模板
                    template:"<h1>随便写的信息</h1>",
                }
            });
    </script>
    

    replace : Boolean or String

    (布尔型)默认为false(模板内容会加载到标签内部),true(模板内容会替换当前标签),即是否替换当前元素中已有的内容

    replace:true,
    注意:如果使用M,必须得配合使用 replace(替换)
    ###priority : Number
    

    优先级,可忽略,默认为0

    注意: ng-repeat 的优先级为1000,这样就可以保证在同一元素上,它总是在其他指令之前被调用
    ###terminal : Boolean
    

    如果为false,则Angular停止运行当前元素上比本指令优先级低的指令。优先级相同的指令还是会被执行

    注意: ng-if 的优先级略高于 ng-view
    priority和terminal的综合运用
    
    <body>
        <hello well good>
            <div>Hello World!!!</div>
        </hello>
    </body>
    <script src="js/angular.min.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        //terminal和priority两个参数只能在同一个元素上设置多个指令才有效
         app.directive("hello",function(){
             return {
                    restrict : "E",
                    priority : 1,
                    link : function(){
                        console.log("hello");
                    }
                }
        });
        app.directive("well",function(){
              return {
                    restrict : "A",
                    priority : 2,
                    link : function(){
                        console.log("well");
                    }
               }
        });
        app.directive("good",function(){
            return {
                    restrict : "A",
                    terminal : true, //这里为true,hello、well指令将停止执行
                    priority : 3,
                    link : function(){
                        console.log("good");
                    }
            }
          });
          app.controller("myCtrl",function($scope){
    
        })
    </script>
    

    template : String or Template Function

    设置模板,必须设置

    template:"<h1>随便写的信息</h1>",
    //template:function(tElement, tAttrs){...},
    ###templateUrl: String
    

    (字符串或函数)

    外部路径的字符串
    接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个外部HTML文件路径的字符串
    模板加载后,AngularJS会将它默认缓存到$templateCach服务中。

    注意:templateUrl 可以提前加载模块到缓存中,提高加载速度
    templateUrl : "html/first.html",
    ###scope: Boolean or Object
    

    当一个控制器实现多个数据时,就需要用到scope属性实现不同的数据。如果要创建一个能够从外部原型继承作用域的指令,将 scope 属性设置为 true

    scope属性的独立作用域

    为true时,从父作用域继承并创建一个自己的作用域
    为false(默认)时,全部继承父作用域
    1).controller属性
    配置属于每个指令自己作用域上的数据(共有),而ng-controller 的作用就是从父级作用域继承并创建一个新的子作用域。

    controller : function($scope){
          $scope.age = 20
    }
    

    设置为一个对象,则能设置 隔离作用域, scope 属性设置为一个空对象 {} 。如果这样做了,指令的模板就无法访问外部作用域了,代码如下:

    directive('myDirective', function() {
          return {
                  restrict: 'A',
                  scope: {},
                  priority: 100,
                  template: '<div>Inside myDirective {{ myProperty }}</div>'
          };
    });
    

    隔离作用域

    将scope属性设置为一个对象,而不是布尔值。隔离作用域默认和父作用域没关系,无法继承它的属性

    1). 设置模板中数据的作用域和绑定规则:
    |@| = |&|
    |:---------------:|:------:|
    | 把当前属性作为字符串传递 |与父作用域中的属性进行绑定素|与父作用域中的函数进行绑定|

    "@" : 本地作用域属性:使用当前指令中的数据和DOM属性的值进行绑定
    “=” : 双向绑定:本地作用域上的属性同父级作用域上的属性进行双向的数据绑定。
    “&” : 父级作用域绑定:通过 & 符号可以对父级作用域进行绑定

    scope : {
            name : "@"  //属性和标签内的属性写一样
    }
    scope: {
          ngModel: '=', // 将ngModel同指定对象绑定
          onSend: '&', // 将引用传递给这个方法
          fromName: '@' // 储存与fromName相关联的字符串
    }
    

    transclude: Boolean

    默认为false,需要创建一个可以包含任意内容的指令时, 才使用 transclude: true 。

    注意:只要使用了 transclude 参数,那么在控制器(下面马上会介绍)中就无法正常监听数据模型的变化了
    

    controller: String or function

    controller: String or function(scope, element, attrs, transclude, otherInjectables) { ... }
    

    注册在应用中的控制器的构造函数,使用函数创建内联控制器

    angular.module('myApp',[]).directive('myDirective', function() {
                 restrict: 'A',
                controller:function($scope, $element, $attrs, $transclude) {
                      // 控制器逻辑放在这里
                }
    })
    

    controllerAs: String

    可以在指令中创建匿名控制器

    angular.module('myApp',[]).directive('myDirective', function() {
              return {
                      restrict: 'A',
                      template: '<h4>{{ myController.msg }}</h4>',
                      controllerAs: 'myController',
                      controller: function() {
                      this.msg = "Hello World"
              }
        };
    });
    

    require: String

    (字符串或数组)字符串代表另外一个指令的名字,如果没有前缀,指令将会在自身所提供的控制器中进行查找,如果没有找到任何控制器(或具有指定名字的指令)就抛出一个错误。例如:

    如果不使用 ^ 前缀,指令只会在自身的元素上查找控制器。
    require: 'ngModel'
    使用 ? 如果在当前指令中没有找到所需要的控制器,会将 null 作为传给 link 函数的第四个参数
    require: '?ngModel'
    使用 ^ 如果添加了 ^ 前缀,指令会在上游的指令链中查找 require 参数所指定的控制器。
    require: '^ngModel'
    使用 ^? 将前面两个选项的行为组合起来,我们可选择地加载需要的指令并在父指令链中进行查找。
    require: '^?ngModel',

    link和compile

    link: link: function(scope, iElement, iAttrs) { ... },
    compile: compile: function(tElement, tAttrs, transclude) { ... },
    

    compile 选项本身并不会被频繁使用,但是 link 函数则会被经常使用。当我们设置了 link 选项, 实际上是创建了一个 postLink() 链接函数, 以便 compile() 函数可以定义链接函数。
    compile 和 link 选项是互斥的。如果同时设置了这两个选项,那么会把 - compile所返回的函数当作链接函数,而 link 选项本身则会被忽略。
    通常情况下,如果设置了 compile 函数,说明我们希望在指令和实时数据被放到DOM中之前进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。
    //用 link 函数创建可以操作DOM的指令。

    require  : 'SomeController',
    link: function(scope, element, attrs, SomeController) {
             // 在这里操作DOM,可以访问required指定的控制器
    }
    compile: function(tElement, tAttrs, transclude) {  
            return {
                pre: function(scope, iElement, iAttrs, controller) { ... },
                post: function(scope, iElement, iAttrs, controller) { ... }
            }
            // 或者
            return function postLink(...) { ... }
        }
    };
    

    注意:指令的生命周期开始于 $compile 方法并结束于 link 方法

    相关文章

      网友评论

        本文标题:angular自定义指令

        本文链接:https://www.haomeiwen.com/subject/lapprxtx.html