AngularJS:指令中的被抄除的内容消失了

时间:2016-06-02 10:28:58

标签: angularjs angularjs-directive angularjs-ng-repeat

我的控制器中有一个列表,由ng-repeat用来创建我的指令。在我的指令中,我使用transclusion附加到指令的元素。

将第一个项目添加到我的列表时,它似乎按预期工作,但是当添加第二个项目时,已删除的内容将从第一个项目的元素中消失。这对我来说毫无意义,因此必定会有一些我误解的事情。

我创建了一个example来重现问题。

添加第一项后,html看起来像预期的那样:

<div ng-controller="ctrl as c" class="ng-scope">
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope">
        <div class="ng-binding">1</div>
        <span class="ng-scope">Transcluded</span>
    </test>
</div>

添加第二个项目后,Transcluded内容不再位于第一个项目的元素中!

<div ng-controller="ctrl as c" class="ng-scope">
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope">
        <div class="ng-binding">1</div>
    </test>
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope">
        <div class="ng-binding">2</div>
        <span class="ng-scope">Transcluded</span>
    </test>
</div>

HTML:

<div ng-app="ui">
  <div ng-controller="ctrl as c">
    <test ng-repeat="item in c.items track by $index" item="item">Transcluded</test>
  </div>
</div>

打字稿:

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

class Controller {
  public items = [];

  constructor($timeout) {
    $timeout(() => this.items.push({Id: 1}), 1000);
    $timeout(() => this.items.push({Id: 2}), 2000);
  }
}
app.controller('ctrl', ['$timeout', Controller]

app.directive('test', function($compile) {
  return {
    scope: {
      item: '='
    },
    transclude: true,
    template: "<div>{{item.Id}}</div>"
    link: function(scope, element, attrs, controller, transcludeFn) {
      console.log("Appending transcluded content to " + scope.item.Id)
      let e = transcludeFn();
      element.append(e);
    }
  };
});

JSFiddle:https://jsfiddle.net/rmytw9cr/2/

1 个答案:

答案 0 :(得分:1)

除非你需要使用transclude功能,否则不要使用它(google上的checkout transclution以获取更多信息,它有点复杂,例如你可以用你选择的范围编译transcluded部分)。 / p>

您可以使用transclude指令进行简单的转换。

尝试以下模板,并从指令中删除转码:

template: "<div><div>{{item.Id}}</div><div ng-transclude></div></div>"

<强>更新 要使用翻译功能,您需要了解它的工作原理。 transclusion函数将回调作为第一个参数。然后,回调函数将获得被转换的html元素的第一个参数。

因此使用它的正确方法是:

transcludeFn(function(compiledHtml) {
    // Do what ever you want with the complied HTML
    // For example: element.append(compiledHtml);
});

transclusion函数也可以获得另一个参数,这是用HTML编译HTML的范围。在这种情况下,您应该提供作为第一个参数的作用域,以及使用已编译的html作为第二个参数的回调:

transcludeFn(someScope, function(compiledHtml) {
    // Do what ever you want with the complied HTML
    // For example: element.append(compiledHtml);
});

对于决赛 - 回调也可以得到第二个参数,这是被转换的范围:

transcludeFn(someScope, function(compiledHtml, transScope) {
    // Do what ever you want with the complied HTML
    // For example: element.append(compiledHtml);
    // Here transScope will be the same as someScope
});

transcludeFn(function(compiledHtml, transScope) {
    // Do what ever you want with the complied HTML
    // For example: element.append(compiledHtml);
    // Here transScope will be the same as directive scope
});