如何在由angular处理之前删除指令?

时间:2015-09-30 04:06:08

标签: javascript angularjs angularjs-directive

我正在尝试创建一个封装标签和输入字段的指令:

<form-field label="Name" ng-model="person.name"></form-field>

指令定义:

app.directive("formField", function(){
    var ignoreAttrs = ["label"];
    return {
      priority: 3, //so it executes before ngModel.
      template: "<div>" +
                     "<label>{{label}}</label>" +
                     "<input type='text' />" +
                    "</div>",
      scope: true,
      compile: function(tElement, tAttrs){
        var $input = tElement.find("input");

        //copy attributes from directive element to inner input field
        var attrs = [];
        $.each(tElement[0].attributes, function(index, attr){
          if(ignoreAttrs.indexOf(attr.label) < 0){
            attrs.push(attr.name);
            $input.attr(attr.name, attr.value);
          }
        });

        //remove the attributes from the directive element
        $.each(attrs, function(index, attr){
          tElement.removeAttr(attr);
        });

        return function postLink(scope, element, attrs){
          scope.label = attrs.label;
        };
      }
    };
  });

我遇到的问题是,当角度遍历DOM时,它会找到两个指令:form-field和ng-model。这导致ng-model在 form-field 元素中设置,然后在输入中设置,当我的意图是只在中使用ng-model时>输入

有没有办法告诉angular忽略一个指令,或者在生命周期的早期时刻我可以运行复制和删除属性的逻辑,因此angular不会在表单字段中找到ng-model指令?

一个可能的解决方案可能是让所有其他指令都有一个前缀,因此angular不能识别它们,然后在 form-field 的编译函数中,我可以在复制到输入,但我正在寻找更清洁的解决方案。

1 个答案:

答案 0 :(得分:1)

由于terminate可能会导致不良副作用,因此最简单且无故障的解决方案是修饰指令以防止它们编译:

app.config(function($provide){
  var blacklistedDirectives = ['ngModel'];

  angular.forEach(blacklistedDirectives, function (directive) {
    $provide.decorator(directive + 'Directive', function ($delegate) {
      angular.forEach($delegate, function (ddo) {
        var compile_ = ddo.compile || function () {};

        ddo.compile = function (element) {
          if (element.attr('form-field') !== undefined || element.prop('tagName').toLowerCase() == 'form-field')
            return;

          return compile_.apply(this, arguments) || ddo.link;
        };
      });

      return $delegate;
    });
  });
});
相关问题