3

AngularJSを使用してシャッフルされたリストを表示したいのですが、最初の2、3の要素のみです。現時点では、このフィドルで示されているように、HTMLテンプレートでシャッフルと制限の両方を実行しています。

<li ng-repeat="value in array | shuffle | limitTo:1">
    {{value}}
</li>

$digestこれは正常に機能しますが、例のように、リストに表示されているよりも多くのアイテムがある場合、Angularは10回の反復を超えます。私が知る限り、何が起こっているのかというと、何かがリストのフィルタリングされた制限された値を監視しているということです。これは、すべての要素が常に表示されるとは限らない場合に変更される可能性が非常に高くなります。

Angularを壊さずにこの効果を達成するにはどうすればよいですか?もちろん、それでも正常に機能しますが、非効率的であり、おそらく私が行っていることが正しくなく、他の方法で達成する必要があることを示しています。

明らかな解決策は、リストが表示される前にコントローラーでリストをシャッフルすることです。ただし、ユーザーがビューを更新するたびに、表示される要素の選択を変更する必要があります。

編集:これが私が達成しようとしていることのより良い例です-アプリは今、あなたが毎回シャッフルされ制限される2つのリストを切り替えることができるようになりました。

4

3 に答える 3

2

前に述べたように、角度は式を待機します。したがって、最良の方法は、配列を表示に渡す前に配列をシャッフルすることです。とにかく、それをきれいに保つのに役立ついくつかのトリックがあります。

http://jsfiddle.net/zc3YH/3/

このフィドルでは、長さを同じに保ちながら、シャッフルの結果をキャッシュします。したがって、配列が変更されたときではなく、長さが変更されたときに、配列が再シャッフルされます。より複雑なキャッシュ動作を実装できます。したがって、主なアイデアは、同じアレイを1回だけシャッフルし、アレイの更新時にのみ再シャッフルすることです。

現在のフィルターの実装は本当に悪いです。単一の配列しかキャッシュしないため、このフィルターを2回使用すると、壊れてしまいます。したがって、キャッシュは、配列が異なる配列になるようにhashKeyなどを使用して実行する必要があります。

shufflemodule.filter('shuffle', function() {
    var shuffledArr = [],
        shuffledLength = 0;
    return function(arr) {
        var o = arr.slice(0, arr.length);
        if (shuffledLength == arr.length) return shuffledArr;
        for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
        shuffledArr = o;
        shuffledLength = o.length;
        return o;
    };
});

とにかく、フィルター内のスコープ内のデータを変更することはお勧めできません。このシャッフルされた配列を共有する必要がある場合は、コントローラー/サービス/ ...でシャッフルします。したがって、var o = arr.slice(0, length)その配列をコピーするため、元の配列は変更されません。

于 2013-02-11T08:30:06.757 に答える
1

このフィドルは、「コントローラーのフィルター」アプローチを示しています。実際にフィルターを作成する代わりに、シャッフルは通常の関数として定義され、に適用され$scope.arrayます。

于 2013-02-11T20:01:20.900 に答える
0

tgatの問題は、フィルターがソース配列を変更することだと思います。新しい配列を返しても、それは非常に問題になります。ダーティチェックの仕組み:「安定化」(または10回の反復)されるまで式を評価し続けます。詳細については、この投稿で説明しています:https ://groups.google.com/forum/m/#!msg/angular/IEIQok-YkpU/InEXv61MrkMJ

解決策は、コントローラーで値を事前にシャッフルすることで、式がダーティチェックフェーズごとに同じ値を返すようにします...申し訳ありませんが、それが今のところ最善の方法です($$ hashでダーティゲームをプレイしてngRepeatにそれを任せたい場合を除きます) yourexpressionは同じ値に評価されます:))

于 2013-02-11T07:44:18.280 に答える