1

Im angular 1.xを使用しており、次のコードでsliderというカスタムディレクティブを作成しました。カスタムディレクティブのトランスコードされたコンテンツを変更するにはどうすればよいですか?

私はtranscludeのスライダディレクティブの内容を、transclude関数内で修正するために試しています。しかし問題はクローンが.slide要素のコレクションを与えていないことです。代わりに、それはng-repeatに関連するコメントを与えます。私は私が成功している何が起こるか今scope.showCurrent.を呼び出すことができるようにng-repeattransclude内部関数の結果にアクセスする方法を知りたい.slide divs.のコレクションである必要がありng-repeatのコンパイル出力、scope.showCurrent() doesntのキャッチ内部$('.slide')コール任意の​​divを取得することはできません呼び出し時には​​要素がないためです。しかし、ng-repeatがtransclude関数内でコンパイルされたhtmlを提供した場合、$('.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> 

は一度transclude内部のコードが実行されているので、あなたが.slide divsを得ることはありません、私のplunk https://plnkr.co/edit/m7YJBNuDjeLPaKkUYK5S?p=preview

+0

なぜここでトランジションを使用しますか?あなたのディレクティブは分離スコープを作成しませんし、通常は内側の要素を外側のスコープにバインドするためにtransclusionが使用されます –

+0

私は[私の答え](http://stackoverflow.com/a/39947320/2545680) 「スライド」。元の意図が何であるかを明確に説明すれば、私は解決策を提供することができるかもしれません –

+0

ありがとうマキシムスそしてあなたが正しいです。私が望んだのは、transclude関数内のクローンの内容を変更することでした。問題は、スライダディレクティブのリンク関数中にレンダリングされていない、別の継承されたディレクティブ自体がngRepeatするためです。私が見つけた回避策は、スコープで表示されたレンダリング完了イベントを通知する別のディレクティブをngRepeatに追加することでした。$ emitとそれをhttp://stackoverflow.com/questions/15207788/calling-a -function-when-ng-repeat-has-finished – XPD

答えて

1

です:

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はまだ利用できません。それは異なる場合がclone 1は、コンパイルの世話をするng-transcludeng-transcludeによって処理されていることとなりますので、あなたの更新

あなたは間違いなくここに

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

この部分は必要ありません。コンテンツをリンクするダイジェストループが実行され、ng-repeatがdiv .slider要素をレンダリングするまで待たなければなりません。そのためには、$timeout

$timeout(function() { 
    scope.showCurrent(scope.slider.currentIndex); 
}); 
関連する問題