angularjs transclude и ng-repeat: все правильно

У меня есть следующий код, который дает не ожидаемый результат:

<div class="outer">1<div>content</div></div>
<div class="outer">2<div>content</div></div>
<div class="outer">3<div>content</div></div>
<div class="outer">4<div>content</div></div>

Вместо этого результат:

<div class="outer">1</div>
<div class="outer">2</div>
<div class="outer">3</div>
<div class="outer">4<div>content</div></div>

Кажется, что ng-repeat выполняется первым и для последнего элемента он обрабатывает transclude. Я знаю, что ng-repeat создает узлы на этапе компиляции, но я думал, что на этапе компоновки функция ссылки вызывается для каждого узла и добавляет внедренный контент.

Может кто-нибудь объяснить, что здесь происходит и как это сделать правильно?

<!DOCTYPE html>
<html ng-app="Transclude">
<head lang="de">
  <meta charset="UTF-8">
  <title>Transclude</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
</head>
<body>

  <outer ng-repeat="counter in [1,2,3,4]" value="counter">
    <div>content</div>
  </outer>

<script>
  angular.module('Transclude', [])

    .directive('outer', function () {
      return {
        restrict: 'E',
        scope: {
          value: '='
        },
        replace: true,
        transclude: true,
        template: '<div class="outer">{{value}}</div>',

        link: function(scope, element, attributes, controller, transclude) {
          var transcludedContent = transclude();
          element.append( transcludedContent );
        }
      };
    })

</script>

</body>
</html>

1 ответ

Решение

Сам по себе transclude() просто связывает содержимое директивы с соответствующей областью действия и возвращает его. То, что вы хотите сделать, это на самом деле клонировать контент (сделать его копию), прежде чем transclude ссылки на него. Поскольку ваш код стоит прямо сейчас, ваш включенный контент просто перемещается из одного экземпляра в другой, заканчивая последним, потому что, ну, это последний.

Вы можете сделать это с помощью cloneAttachFn. Вы передаете это, чтобы включить.

    link: function(scope, element, attributes, controller, transclude) {
      transclude(scope, function(clone) {
          element.append( clone );
      });

    }
Другие вопросы по тегам