13

私は AngularJS を初めて使用し、jQuery カスタム コンテンツ スクローラーをアプリケーションに実装する際に問題に対処しています。

Angular でコンテンツを更新するときに、スクローラーを更新する必要があります。このため、スクローラーにはupdateメソッドがあります。私の問題は、どこに電話すればよいかわからないことです。コンテンツのマークアップは次のとおりです。

<div class="scroll-list nice-scrollbars">
    <ul class="gallery clearfix">
        <li class="extra-alt" ng-repeat="item in relatedItems.data">
            ...
        </li>
    </ul>
</div>

Angular の成功ブランチで更新メソッドを呼び出そうとしました$http.post:

$scope.relatedItems = $http.post($scope.url, {
    'filterType': 'related', 'film': id
}).success(function() {
    $(".nice-scrollbars").mCustomScrollbar('update');
});

これは機能しませんでした。成功メソッドが呼び出されたときに、ビューのコンテンツがまだ更新されていないためだと思います(alert関数を使用して表示でき、ダイアログボックスを閉じた後にデータが表示されました)

スクロールバーを機能させることができた唯一の方法は、スクロールバーの高度なプロパティを使用してコンテンツの変更を監視することでした (これらはスクロールバーに渡されるオプションです)。

var scrollbarOpts = {
    scrollButtons:{
        enable:true
    },
    advanced:{
        updateOnContentResize: true
        //@TODO: get rid of this, correctly find where to call update method
    }
}

このオプションはスクリプト全体のパフォーマンスを低下させるため、これは悪い習慣です。 必要に応じてDOMを更新するために必要なjQueryメソッドを呼び出す正しい場所はどこですか、または変更を表示するためのそのようなバインディングはAngularJSでどのように正しく行われますか?

4

1 に答える 1

14

DOM 操作は、(コントローラーではなく) ディレクティブで行う必要があります。ディレクティブはモデルの変更を $watch() する必要があり、watch コールバックは jQuery DOM 操作を実行する必要があります。Angular が DOM を更新/変更した後 (ただし、ブラウザーがレンダリングする前)、jQuery コードを実行するために $evalAsync が必要になることがあります。$timeoutブラウザーのレンダリング後に何らかのアクションを実行する場合に使用します)。この回答を参照してください。ここでは、ディレクティブを $watch() モデル プロパティに使用する方法を示すフィドルを提供し、モック fetch() 関数で $evalAsync を使用しました。

あなたの特定のケースでは、最初にディレクティブで次のことを試すことをお勧めします。

scope.$watch("relatedItems.data", function() {
   $(".nice-scrollbars").mCustomScrollbar('update');
});

それでもうまくいかない場合は、これを試してください:

scope.$watch("relatedItems.data", function() {
   scope.$evalAsync(  // you might need to wrap the next line in a function, not sure
      $(".nice-scrollbars").mCustomScrollbar('update')
   );
});
于 2012-12-22T17:36:37.177 に答える