Fork me on GitHub

angular之directive详解二

前言

这里主要是因为angular自定义指令的内容太多,分开写,比较好阅读,所以是衔接anglar值directive详解一

下面内容都是自己一点点写上去的,如果有什么问题,请及时指正,若要转载请备注作者,谢谢配合。


directive中第二个参数中返回对象的配置项

controller

  • 作用: 控制指令的作用域, 可以实现指令和控制器之间交流,或者指令与指令之间交流。
  • 取值: 一般是一个Function
  • 指令与控制器间交流

    • 通过scope属性控制,如何和父级控制器的作用域
    • js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      angular.module('app', [])
      .directive('myDirectiveController', function(){
      return {
      restrict: 'EA',
      controller: function($scope, $element, $attrs){
      // 指令控制器的逻辑代码
      $scope.list = ['zs', 'ls', 'ww'];
      },
      templateUrl: 'template.html'
      }
      })
      <script type="text/ng-template" id="template.html">
      <ul>
      <li ng-repeat="item in list">{{item}}</li>
      </ul>
      </script>
    • html

      1
      2
      <my-directive-controller>
      </my-directive-controller>
    • demo
      http://zjrzpp.gitee.io/directivecase/#!/ctrl

  • 指令与指令之间交流
    • 与require配合使用,将在之后require中的案例中体现

controllerAs

  • 作用:用于设置控制器的别名,以此名发布控制器,并且作用域可以访问controllerAs。
  • 取值: String
  • 注解:定义了别名,这样在controller中可以使用this代替$scope,但是如果controller里面使用$watch的话还是要用$scope.$watch()。
  • js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <script type="text/javascript">
    angular.module('app', [])
    .controller('demoCtrl', ['$scope', function($scope){
    }])
    .directive('myDirectiveControllerAs', function(){
    return {
    restrict: 'EA',
    controller: function($scope, $element, $attrs){
    // 指令控制器的逻辑代码
    this.list = ['zs', 'ls', 'ww'];
    this.myClick = function() {
    alert('我被点击了')
    }
    },
    // 控制器的别名
    controllerAs: 'myCtrl',
    // link中的第四个参数表示注入了控制器myCtrl,这样就可以使用它通过this定义的方法和属性了
    link: function(scope, ele, attrs, myCtrl) {
    ele.on('click', myCtrl.myClick);
    },
    templateUrl: 'template.html'
    }
    })
    </script>
    <script type="text/ng-template" id="template.html">
    <ul>
    <li ng-repeat="item in myCtrl.list" >{{item}}</li>
    </ul>
    </script>
  • html

    1
    2
    3
    <div ng-controller="demoCtrl">
    <my-directive-controller-as></my-directive-controller-as>
    </div>
  • result
    ctrlAs

  • demo
    http://zjrzpp.gitee.io/directivecase/#!/ctrlas

    require

  • 作用:将父子指令或者兄弟指令之间架起一个桥梁,将其值所指定的指令中的控制器注入到当前指令中,并作为当前指令的link函数的第四个参数。
    • 它有两个修饰符:
      • ? : 如果require没有找到相应的指令避免报错,还能确保程序的正常执行。我测试一般是兄弟指令可以直接这样取值,但是如果是父子指令的话单独这样取值link的第四个参数会返回null
      • ^ : 表示往父级或者兄弟指定查找。
      • ?^:组合使用,表示两者的意思。
  • 取值:Sring || Array
    • String:一个指令的名字,例如’^a’
    • Array:多个指令的名字,例如[‘^a’,’^b’]
  • js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    <script type="text/javascript">
    angular.module('app', [])
    .controller('demoCtrl', ['$scope', function($scope){
    }])
    .directive('myDirectiveRequire', function(){
    return {
    restrict: 'EA',
    transclude: true,
    controller: function($scope, $element, $attrs){
    // 指令控制器的逻辑代码
    $scope.list = ['zs', 'ls', 'ww'];
    // 在这里把控制看成一个构造函数
    this.myClick = function() {
    alert('我是requireChild的父亲节点')
    }
    },
    templateUrl: 'template.html'
    }
    })
    .directive('requireChild', function() {
    return {
    restrict :'EA',
    // 以数组的形式引入多个其他的指令
    require: ['^myDirectiveRequire', '?requireSibling','?test'],
    // 这里的第四个参数是数组,因为require的取值是数组
    // 如果require的取值是字符串,这里就是一个object,不过也可能为null,具体还要根据require的修饰符决定
    link: function(scope, ele, attr, myCtrl){
    console.log(myCtrl)
    myCtrl[0].myClick();
    console.log(myCtrl[1].msg)

    }
    }
    })
    .directive('requireSibling', function() {
    return {
    restrict :'EA',
    controller: function($scope) {
    this.msg = '我是requireChild的兄弟指令'
    }
    }
    })
    .directive('test', function(){
    return {
    restrict: 'E',
    controller: function(){
    this.test = '我是测试指令'
    }
    }
    })
    </script>
    <script type="text/ng-template" id="template.html">
    <ul>
    <li ng-repeat="item in list" >{{item}}</li>
    </ul>
    <div ng-transclude></div>
    </script>
  • html

    1
    2
    3
    4
    5
    6
    7
    8
    <div ng-controller="demoCtrl">
    <test></test>
    <my-directive-require>
    <require-child require-sibling>

    </require-child>
    </my-directive-require>
    </div>
  • result
    reqire

  • demo
    http://zjrzpp.gitee.io/directivecase/#!/require
  • 作用:用来创建可以操作DOM的属性
  • 取值: Function
    • 参数1:scope
    • 参数2:element
    • 参数3:attr
    • 参数4: require取值的控制器,可能是一个Obejct也可能是一个数组,或者是null
  • 和controller有什么不同
    1. 我觉得主要区别是:link函数一般用来操作DOM元素,而controller一般用来操作数据,用于指令之间传递

compile

  • 作用:可以操作DOM元素,也可以返回一个Function,这个function就是link链接函数
  • 取值:Function
  • js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    angular.module('app', [])
    .controller('demoCtrl', ['$scope', function($scope){
    $scope.list = [
    {name: 'zpp'}, {name: 'www'}, {name: 'qqq'}];
    }])
    .directive('compileDom', function(){
    return {
    restrict: 'EA',
    replace: true,
    template: '<p>{{item.name}}</p>',
    // 定义了compile就不需要定义link,当compile返回一个方法这个方法就是link
    // tElement 正在执行该指令的当前dom元素的jquery对象
    // tAttrs 正在执行该指令的当前dom元素的属性
    compile: function(tElement, tAttrs, transclude){
    console.log('编译阶段开始执行');
    // 改变当前元素的DOM结构
    tElement.append(angular.element('<span>我是添加进来的</span>'));
    return {
    // pre:编译阶段执行
    pre: function preLink(scope, iElement, iAttrs, controller) {
    console.log('preLink...');
    },
    // post: 所有子元素指令的post都执行后执行
    post: function postLink(scope, iElement, iAttrs, controller){
    iElement.on('click', function(){
    scope.item.name = 'click aaa'
    scope.$apply();
    })
    console.log('postLink ....');
    }

    };//return
    // compile直接返回的一个方法,就是postLink
    },
    // 这个方法不会再执行了
    link: function(scope, ele, attrs, ctrl) {
    console.log('我还会执行吗')
    }
    }
    })
  • html

    1
    2
    3
    4
    5
    <div ng-controller="demoCtrl">
    <ul>
    <li ng-repeat="item in list" compile-dom></li>
    </ul>
    </div>
  • reslut
    compile

  • demo
    http://zjrzpp.gitee.io/directivecase/#!/compile

连续写了两天,终于把自定义指令的基本配置参数给写完了,现在感觉脑子里好清楚,但是觉得还有好多东西要写,之后我会继续总结angular自定义指令之间的高级应用,欢迎学习。

-------------本文结束感谢您的阅读-------------