AngularJS - 动态地向元素添加指令

时间:2013-12-05 15:36:18

标签: angularjs angularjs-directive

我创建了一个指令,用于检查数据是否以下列方式输入到HTML元素:

var myApp = angular.module('myApp', []);

myApp.directive("uiRequired", function () {
return function (scope, elem, attrs) {
    elem.bind("blur", function () {
        var $errorElm = $('#error_testReq');
        $errorElm.empty();
        if (angular.isDefined(attrs) && angular.isDefined(attrs.uiRequired) && attrs.uiRequired == "true" && elem.val() == "") {
            $errorElm.append("<li>Field value is required.</li>");
            $errorElm.toggleClass('nfx-hide', false);
            $errorElm.toggleClass('nfx-block', true);
        }
        else
        {
            $errorElm.toggleClass('nfx-hide', true);
            $errorElm.toggleClass('nfx-block', false);
        }
    });
};

});

可以看到一个工作示例here

我的问题: 有没有办法将我已创建的指令(uiRequired)动态添加到文档就绪的屏幕上的元素上。

我想根据我预先定义的列表将新指令放在选定的HTML元素上。我不能事先知道这个指令必须在哪个领域。

所以我必须在页面渲染时把它放进去。

我已经尝试在页面加载时自动动态添加它,但是AngularJS确实解释了它。

我在互联网上找不到这样做的例子。

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

当Angular遍历DOM并将元素与指令匹配时,您可以在编译阶段动态地将指令添加到页面。编译过程的每一步都可以在它之前转换DOM树,但是你永远不应该修改Angular已编译的元素。这一点很重要,因为向已经走过的元素添加指令将不起作用。当然,有办法解决这个问题。例如,您可以重新编译并重新链接以前遍历的元素。但是我强烈建议不要这样做,因为它可能会导致意外的副作用,例如内存泄漏和性能降低。

要动态添加uiRequired指令,您可以创建父指令 - 让我们将其命名为uiRequiredApplier。

app.directive('uiRequiredApplier', function($scope) {
      return {
           restrict: 'A',
           compile: function(element, attr) {
                 // you can apply complex logic figure out which elements
                 // you want to add the uiRequired attribute to
                 $('input', element).attr('uiRequired','');
                 return function(scope, element, attr) {
                 }
           }
      }
});

然后您可以应用如下属性:

<div ui-required-applier>
    <input type="text" ng-model="name" />
</div> 

编译uiRequiredApplier时,它将使用尚未编译的jQuery动态地将uiRequired属性添加到所选元素。当Angular遍历DOM时,最终它将编译并链接uiRequired属性,这将添加所需的验证行为。