8

隠しアイテムのリストがあります。リストを表示してから、1 回のクリックでそのうちの 1 つにスクロールする必要があります。ここでコードを再現しました: http://plnkr.co/edit/kp5dJZFYU3tZS6DiQUKz?p=preview

コンソールを見ると、アイテムが表示される前に scrollTop() が呼び出されているため、ng-show はインスタントではなく、このアプローチは間違っていると思います。scrollTop() をタイムアウトで延期すると機能しますが、私はそれをしたくありません。

他の解決策はありますか?

4

2 に答える 2

16

scrollTop()の使用時にの呼び出しを延期する以外に解決策はありませんng-show。モデルの変更が DOM に反映されるまで待つ必要があるため、要素が表示されます。それらがすぐに表示されない理由は、スコープのライフ サイクルです。内部では、クリック ハンドラーで完全なコードを実行したにスコープの関数が呼び出されng-showたときにのみ起動されるウォッチ リスナーを使用します。$digest()

スコープのライフ サイクルの詳細については、http://docs.angularjs.org/api/ng.$ro​​otScope.Scopeを参照してください。

通常、このイベントの後に次のように遅延なしで実行されるタイムアウトを使用することは問題になりません。

setTimeout(function() {
    $(window).scrollTop(50);  
}, 0);

タイムアウトのない代替ソリューション:

ただし、タイムアウト イベント (イベント キュー内の他のイベントが先行して実行される可能性があります) を回避したい場合は、クリック イベント ハンドラー内でスクロールが発生するようにしてください。コントローラーで次のことができます。

$scope.$watch('itemsVisible', function(newValue, oldValue) {
    if (newValue === true && oldValue === false) {
        $scope.$evalAsync(function() {
            $(window).scrollTop(50);
        });
    }
});

ウォッチ リスナーは、ディレクティブ$digest()によって登録されたウォッチ リスナーと同じ呼び出し内で起動します。ng-showに渡された関数は$evalAsync()、すべてのウォッチ リスナーが処理された直後に angular によって実行されるため、要素はng-showディレクティブによって既に可視化されています。

于 2013-11-10T12:11:01.973 に答える