【问题标题】:AngularJS : How to properly transclude child elements in custom directive?AngularJS:如何在自定义指令中正确嵌入子元素?
【发布时间】:2013-12-16 17:54:42
【问题描述】:

这里有一些代码:link

我正在尝试创建一个指令,将其子项包装在一些样板文件中。但是如果孩子们有ng-if控制他们的外表,那么“嵌入”就不起作用了。好吧,确实如此,但正如您所见,ng-if 逻辑没有正确通过。

我想知道如何修复它,以及 Angular 文档中描述的位置(如果有的话)。

【问题讨论】:

    标签: angularjs angularjs-directive transclusion


    【解决方案1】:

    问题是 Angular 最初将 ngIf 替换为注释,用于跟踪条件代码的放置位置。举个例子最容易看出。

    您的 HTML:

    <div control-group>
      <label>Test</label>
      <input type="text" ng-model="editing.name" />
      <span class="text-error" ng-if="editing.name.length != 3"> Name must be 3 characters </span>
    </div>
    

    在您的 transclude 函数的 cloned 变量 (transclude(function (cloned) {) 中看起来像这样:

    <div control-group>
      <label>Test</label>
      <input type="text" ng-model="editing.name" class="ng-valid ng-dirty">
      <!-- ngIf: editing.name.length != 3 -->
    </div>
    

    因此,您要过滤的类 text-error 的元素(如下)不在 cloned 中。只是评论在那里。

    var inputsAndMessages = cloned.filter('input, button, select, .text-error');
    

    由于您只包含与上述过滤器匹配的元素,因此ngIf 注释将丢失。

    解决方案也是过滤 cmets 并将它们添加到您的追加中(因此 Angular 保持它对 ngIf 的引用点)。一种方法是用这个替换上面的内容(使用 html 注释是节点类型 8 的事实)

    var messages = cloned.filter(function(){ return this.nodeType == 8; }); //comments
    
    var inputs = cloned.filter('input, button, select')
    
    var inputsAndMessages = inputs.add(messages);
    

    Working plunker

    【讨论】:

    • 好的,这行得通——你已经解释了发生了什么。我猜在真实的代码中,由于我不知道子元素上是否会有ng-if,所以我需要自己设置指令定义terminal: true$compile。这样我就可以在任何 ng-if 被编译并变成评论之前重新排列元素。
    【解决方案2】:

    您需要使用ng-transclude 指令告诉指令将子元素放置在何处:(plnkr)

     template: "<div class='control-group' ng-transclude>" +
                     "<label class='control-label' for=''></label>" +
                     "<div class='controls'></div>" +
                  "</div>",
    

    来自文档:

    为使用嵌入的最近父指令的嵌入 DOM 标记插入点的指令。

    该指令所在元素的任何现有内容都将在插入嵌入内容之前被删除。

    我不确定您的意图究竟是什么,因为您在模板中和 HTML 中都有 inputlabel。您可能想将您的 ng-transclude 放在其他地方。

    【讨论】:

    • 我不能使用ng-transclude,因为我想在模板中的不同点嵌入我的输入子元素。所以我需要使用更灵活的translude 函数。我可能应该将这一点添加到我的问题中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2017-08-16
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    相关资源
    最近更新 更多