1

使用angular 1.x的Im我創建了一個名爲slider的自定義指令,如下面的代碼。如何修改自定義指令的transcluded內容?

我試圖transclude滑塊指令的內容,以便在transclude函數內修改它。但問題是克隆沒有給出一組.slide元素。相反,它給出了與ng-repeat有關的評論。我不能得到的ng-repeat編譯後的輸出應該是.slide divs.集合我想知道如何訪問內部transclude功能ng-repeat的結果,這樣我可以成功調用scope.showCurrent.會發生什麼現在是,$('.slide')調用內部scope.showCurrent()犯規捕捉任何​​的div因爲在通話時沒有​​元素。但是,如果ng-repeat提供了其編譯的html裏面的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

+0

爲什麼要在這裏使用跨越?你的指令不會創建隔離範圍,並且通常使用transclusion來將內部元素綁定到外部範圍 –

+0

我在[我的答案](http://stackoverflow.com/a/39947320/2545680)中解釋了爲什麼你沒有得到'slides'。如果你明確地解釋了你的初衷,我可能會提供一個解決方案 –

+0

Thanks Maximus,你說得對。我想要的是修改transclude函數內部的克隆的內容。問題是我認爲它是因爲ngRepeat本身是另一個在我創建的slider指令的鏈接函數中沒有呈現的transcluded指令。我發現的解決方法是在ngRepeat上添加另一個指示符,它指示渲染完成事件,該事件使用範圍發射。$ emit和catch在滑塊指令中,如http://stackoverflow.com/questions/15207788/calling-a -function-when-ng-repeat-has-finished – XPD

回答

1

你沒有得到.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); 
}) 

這一部分,因爲這將是不同的clone通過ng-transcludeng-transclude處理的人會採取編制的關懷和鏈接內容。您必須等到digest循環運行,ng-repeat纔會呈現div .slider元素。爲此,請使用$timeout

$timeout(function() { 
    scope.showCurrent(scope.slider.currentIndex); 
}); 
相關問題