如何修改自定义指令的嵌入内容?

How to modify the transcluded content of a custom directive?

我正在使用 angular 1.x 并且我创建了一个名为 slider 的自定义指令,如下代码所示。

我正在尝试 transclude 滑块指令的内容,以便在 transclude 函数中修改它。但问题是克隆没有给出 .slide 元素的集合。相反,它给出了与 ng-repeat 相关的注释。我无法获得 ng-repeat 的编译输出,它应该是 .slide divs. 的集合 我想知道如何在 transclude 函数中访问 ng-repeat 的结果,以便我可以成功call scope.showCurrent. 现在发生的是,$('.slide')scope.showCurrent() 内调用没有捕获任何 .slide div,因为在调用时没有 .slide 元素。但是,如果 ng-repeat 提供了其已编译的 html inside transclude 函数,$('.slide') 将捕获 div。

app.directive('slider', function ($compile) {
     return {
          restrict: 'EA',
          priority: 1200,
          scope: true,
          controller: function ($scope) {
               $scope.slider = { currentIndex: 0 };
          },
          transclude:'element',
          link: function (scope, el, attrs, ctrl, transclude) {

               scope.showCurrent = function (currentIndex) {
                    console.log('x')
                    $('.slide').hide();
                    $('.slide').eq(currentIndex).show();
               }

               scope.$watch('slider.currentIndex', function (val) {
                    console.log('tst');
                    scope.showCurrent(val);
               });

               transclude(scope, function (clone) {
                    el.after(clone);
                    scope.showCurrent(scope.slider.currentIndex);
               })
          },
     }
});

以下是该指令的html用法。

<slider>
  <div ng-repeat="slide in slides" class="slide">
     <div>Image {{img}}</div>
     <img ng-src="img"/>
   </div>
</slider>

这是我的废话 https://plnkr.co/edit/m7YJBNuDjeLPaKkUYK5S?p=preview

你没有得到 .slide divs 因为当时正在执行你在 transclude 中的代码:

el.after(clone);
scope.showCurrent(scope.slider.currentIndex);

内部内容的链接功能,特别是ng-repeat的链接功能,还没有执行。在此链接函数中,为 slides.

添加了观察者

即使您等到链接函数执行完毕,如下所示:

transclude(scope, function (clone) {
    el.after(clone);
    scope.showCurrent(scope.slider.currentIndex);
})
// here the linking functions of the `clone` have already been executed

.slide divs 在第一个摘要循环运行之前仍然不可用。

更新后

这里绝对不需要这部分

transclude(scope, function (clone) { 
    el.after(clone); 
    scope.showCurrent(scope.slider.currentIndex); 
})

因为 cloneng-transclude 处理的不同 ng-transclude 将负责编译和链接内容。您必须等到摘要循环运行并且 ng-repeat 呈现 div .slider 元素。为此,使用 $timeout:

$timeout(function() {
    scope.showCurrent(scope.slider.currentIndex);
});