AngularJS - 指令详解

指令定义

AngularJS应用的模块中有很多方法可以使用,其中directive()这个方法是用来定义指令的:

angular
  .module('myApp', [])
  .directive('myDirective', myDirective);

myDirective.$inject = ['$timeout', 'UserDefinedService']
function myDirective($timeout, UserDefinedService) {
  // 指令定义放在这里
}

directive()方法可以接受两个参数:

  1. name(字符串)
    指令的名字,用来在视力中引用特定的指令。
  2. factory_function(函数)
    这个函数返回一个对象,其中定义了指令的全部行为。$compile服务利用这个方法返回的对象,在DOM调用指令时来构造指令的行为。

为了避免与未来的HTML标准冲突,给自定义的指令加入前缀来代表自定义的命名空间。AngularJS本身已经使用了ng-前缀,所以可以选择除此以外的名字。在例子中我们使用my-前缀(比如my-derictive)。

下面,来看看定义一个指令时可以使用的全部设置选项。
可能的选项如下所示,每个键的值说明了可以将这个属性设置为何种类型或者什么样的函数:

angular
  .module('myApp', [])
  .directive('myDirective', myDirective);

function myDirective() {
  return: {
    restrict: String,
    priority: Number,
    terminal: Boolean,
    template: String or Template Function:
      function(tElement, tAttrs) {...},
    templateUrl: String,
    replace: Boolean or String,
    scope: Boolean or Object,
    transclude: Boolean,
    controller: String or
      function(scope, element, attrs, transclude, otherInjectables) {...},
    controllerAs: String,
    require: String,
    link: function(scope, iElement, iAttrs) {...},
    compile: // 返回一个对象或连接函数,如下所示:
      function(tElement, tAttrs, transclude) {
        return {
          pre: function(scope, iElement, iAttrs, controller) {...},
          post: function(scope, iElement, iAttrs, controller) {...}
        }
        // 或者
        return function postLink(...) {...}
      }
  }
}

restrict(字符串)

restrict是一个可选的参数。它告诉AngularJS这个指令在DOM中可以何种形式被声明。默认AngularJS认为restrict的值是A,即以属性的形式来进行声明。
可选值如下:
E(元素)

<my-directive></my-directive>

A(属性,默认值)

<div my-directive="expression"></div>

C(类名)

<div class="my-directive:expression;"></div>

M(注释)

<!-- directive:my-directive expression -->

这些选项可以单独使用,也可以混合在一起使用。

优先级(数值型)

优先级参数可以被设置为一个数值。大多数指令会忽略这个参数,使用默认值0,但也有些场景设置高优先级是非常重要甚至是必须的。例如,ngRepeat将这个参数设置为1000,这样就可以保证在同一元素上,它总是在其他指令之前被调用。
如果一个元素上具有两个优先级相同的指令,声明在前面的那个会被优先调用。如果其中一个的优先级更高,则不管声明的顺序如何都会被优先调用:具有更高优先级的指令总是优先运行。

terminal(布尔型)

terminal是一个布尔型参数,可以被设置为true或false。
这个参数用来告诉AngularJS停止运行当前元素上比本指令优先级低的指令。但同当前指令优先级相同的指令还是会被执行。
如果元素上某个指令设置了terminal参数并具有较高的优先级,就不要再用其他低优先级的指令对其进行修饰了,因为不会被调用。但是具有相同优先级的指令还是会被继续调用。

template(字符串或函数)

template参数是可选的,必须被设置为以下两种形式之一:

  • 一段HTML文本;
  • 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符串。tElement和tAttrs中的t代表template,是相对于instance的。在讨论链接和编译设置时会详细介绍,模板元素或属性与实例元素或属性之间的区别。

templateUrl(字符串或函数)

templateUrl是可选的参数,可以是以下类型:

  • 一个代表外部HTML文件路径的字符串;
  • 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串。

replace(布尔型)

replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默认值意味着模板会被当作子元素插入到调用此指令的元素内部:

<div some-directive></div>
.directive('someDirective', function() {
  return {
    template: '<div>some stuff here</div>'
  }
})

调用指令之后的结果如下(这是默认replace为false时的情况):

<div some-directive>
  <div>some stuff here</div>
</div>

如果replace被设置为了true:

.directive('someDirective', function() {
  return {
    replace: true, // 修饰过
    template: '<div>some stuff here</div>'
  }
})

指令调用后的结果将是:

<div>some stuff here</div>

#

支付宝扫码打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者