AngularJS:如何将一个元素传递到使用ng-repeat的模板中?

5
我有一个旋转木马指令,其中包含一些分块操作,将传入的items数组映射为元素结构的数组,然后生成类似于下面伪代码的标记:

<array of arrays>

  <array of items>
    <item>
    <item>
  </array of items>

  <array of items>
    <item>
    <item>
  </array of items>

</array of arrays>

这个的angular模板看起来像这样:
<div class="carousel__content" ng-style="carousel.containerWidth">
  <ul class="carousel__chunk" ng-repeat="chunk in carousel.chunks" ng-style="carousel.chunkWidth">
    <li class="carousel__item" ng-repeat="item in chunk" ng-style="carousel.itemWidth">
      <div class="carousel__item-content">

        [element should be transcluded into this spot.]

      </div>
    </li>
  </ul>
</div>

假设我的视图代码如下:

<!-- The <a> tag should appear inside the 'carousel.html' template's ng-repeat list. -->
<carousel items="items" config="config">
  <a href="#">{{ item.name }}</a>
</carousel>

我希望将嵌套元素与最深层的ng-repeat中的item对象绑定。这里提供了一个具有简化测试用例的完整Plunker:http://plnkr.co/edit/kYItcXV0k9KvnpiYx1iG。问题在于我无法在ng-repeat内部放置ng-transclude属性,并且(正如Plunkr中的carousel.js指令文件所示)我似乎也无法使用compile步骤中的transclude()函数手动注入要进行转换的标记。如果您有任何想法,将不胜感激。
1个回答

6
在现有指令的链接函数中,使用引用传递函数设置一个变量:
 post: function($scope, $element, attrs) {
     $scope.transclude = transclude; 
     ...

然后,创建一个新的指令,用于取代在您希望传输内容出现的元素上使用的ng-transclude:

.directive('innerTransclude', function(){
  return function(scope, elem, attrs){
    scope.transclude(scope, function(clone){
      elem.append(clone);
    });
  }
})

这个指令将clone追加到元素中,同时避免了在使用transclusion本身的元素内部尝试使用transclusion时出现的问题。不要忘记将其添加到您的模板中:

<div class="carousel__item-content" inner-transclude></div>

演示


完美,正好符合我的需求,谢谢。不过我有一个问题:您能否解释一下为什么这样做可以工作,而不是在预编译步骤中使用transclude函数?我还是无法完全理解。 - Jannis
4
这实际上是一个漏洞,已经在最新的1.3测试版中修复。这个解决方案是旧版本的权宜之计。基本上,你不能在模板中使用另一个指令使用的嵌套传输功能内部使用ng-transclude。这个解决方案之所以有效,是因为它将传输函数存储在一个变量中,不受嵌套的传输指令的影响,并且执行与ng-transclude相同的操作,但实际上没有使用它。 - Marc Kline
2
这是你的 Plunker 的另一个分支,使用了最新的 beta 版本。你会注意到它的工作方式与你最初预期的一样。 - Marc Kline
太棒了,非常感谢您的解释,知道我至少走在了正确的道路上 :) - Jannis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接