AngularJS:如何在custom指令中正确转换子元素?

时间:2013-12-16 17:54:43

标签: angularjs angularjs-directive transclusion

以下是一些代码:link

我正在尝试创建一个将其子代包装在某个样板中的指令。但是,如果孩子们ng-if控制他们的外表,那么“翻译”就不起作用了。好吧,但是你可以看到ng-if逻辑没有正确传递。

我想知道如何解决它,但也想知道Angular文档中描述的内容(如果有的话)。

2 个答案:

答案 0 :(得分:2)

你需要告诉指令在哪里放置带有ng-transclude指令的子元素:(plnkr

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

来自文档:

  

指示使用包含转义的最近父指令的转换DOM的插入点的指令。

     

在插入转换内容之前,将删除放置此指令的元素的任何现有内容。

由于模板中的inputlabel以及HTML中的子项,我不确定您的意图是什么。您可能希望将ng-transclude放在其他位置。

答案 1 :(得分:2)

问题是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>

在您的转化功能的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评论将丢失。

解决方案也会过滤注释并将其添加到您的追加中(因此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