【问题标题】:How to write an AngularJS directive that creates DOM elements that are other directives?如何编写一个 AngularJS 指令来创建其他指令的 DOM 元素?
【发布时间】:2014-04-02 03:45:53
【问题描述】:

我正在编写一些非常复杂的 DOM 操作,这肯定会测试我编写非常复杂的指令的能力。我没有遇到任何示例(我认为无论如何)可以证明我想做的事情。

假设我有一个小部件列表,它可以是不同类型的。这些小部件需要在<ul> 元素中显示。不过,每种类型的小部件可能不同,因此<li> 中每个小部件的实际标记将大不相同。

如果我只需要标准标记,我认为实现这一点并不难,但是这些小部件中的每一个都必须依次创建我希望 Angular 处理的 html 片段。它们可能很简单,比如想使用ng-click,但也可能更复杂一些,比如也想使用我自己的自定义指令。

理想情况下,我想分别为每个小部件创建指令,只是为了分离关注点,因为我认为它们中的大多数代码本身将非常复杂。然后,我可能想让另一个指令检查小部件的类型并创建一个使用各个小部件指令的 html 片段。那有意义吗?如果不是,那么我可能想以类似的方式分离关注点。

有没有办法做到这一点?

【问题讨论】:

  • 我认为您建议的方法没有根本问题。如何做到这一点的确切答案取决于你的小部件的定义方式——也许你可以详细说明一下?为了创建一个“超级指令”来创建实际的小部件,我猜$compile 会派上用场。
  • @Mikke 我之前实际上从未使用过$compile,虽然很多时事通讯、文章等都在谈论它,但我从未真正看到过如何使用它的示例。我对 Angular 还是很陌生,所以当涉及到真正复杂的东西时,我有点害怕。到目前为止,我已经制作了大约 30 多个指令,但它们都不需要使用 compile。我的小部件被定义为 json。它们来自服务器。构建小部件的所有数据都将作为 json 对象图发送。
  • 这取决于您的使用情况。如果另一个指令是在您自己的指令模板中定义的,它应该与您的指令一起编译。如果您使用指令以编程方式添加新内容,则需要 $compile。我正在使用这样的东西来添加一些验证显示消息:inputElement.after($compile('<span class="help-block" ng-show="showRequiredError()">Required</span>')(scope));

标签: javascript jquery html angularjs angularjs-directive


【解决方案1】:

尽管该问题对不同的解决方案开放,但您建议的策略似乎是合理的,该策略使用负责创建包含在某些数据结构中的小部件的“超级指令”。正如我在评论中已经说过的那样,我认为这没有任何根本问题,尽管精简它可能是一个挑战。

为了用一些工作代码说明基本思想,使用$compile,请参阅fiddle

假设一个范围绑定的数据结构

$scope.widgets = [
    {directive: 'widget-directive-one'},
    {directive: 'widget-directive-two'},
];

带模板

<ul>
    <li ng-repeat="widget in widgets" super-directive="{{ widget.directive }}"></li>
</ul>

“超级指令”可以像这样编译给它的指令:

angular.module('myApp').directive('superDirective', function($compile) {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {

            // Create an element of the correct type
            var widgetElement = document.createElement(attrs.superDirective);

            // Possibly modify widgetElement here

            // Compile the element and append it to the LI element
            elem.append($compile(widgetElement)(scope));
        }
    };
});

将此指令视为概念证明。它可能需要大量工作才能按您的意愿运行,其中大部分取决于设计选择。

【讨论】:

  • 这比我预期的要简单得多。工作精美。谢谢!
  • 呵呵,第一次了解$compile,感觉自己是个超级英雄,想到了这个XKCD:xkcd.com/208
  • 在此处注入和使用$document 而不是仅仅使用document 来促进单元测试可能是有意义的。
猜你喜欢
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
相关资源
最近更新 更多