2017-07-21 10 views
0

現在、配列内の配列の内容を表示しています($scope.array)。部分の後に配列部分を表示しようとしています

リクエストのある配列の内容をmy servにロードします。 悲しいことに、$scope.arrayには多くの要素が含まれています。一度にすべての要素を表示するにはしばらく時間がかかります。

ユーザーエクスペリエンスを向上させるために、配列を部分的に表示したいと考えています。最初は、にチャンクでデータチャンクを追加するだけで、$scopeが処理できると思ったのですが、それはいいです。

現在の$digestループは、配列が一杯になったときだけ終了することがわかりました。 $digest問題を回避する方法を期待して、非同期的にチャンクを$scopeに追加しようとしましたが、動作しません。

今、データを正しく表示するためのアイデアが不足しています。この種の問題に関する経験があれば、それについて聞いてうれしいですね。

ありがとうございます。

+1

とにかく20k行のテーブルを読むのに誰も時間を費やすことはありません。問題は解決しました:) –

+1

ページネーション?それを試してください。配列の一部を表示し、ボタンを追加して残りの部分を表示します。 – kawadhiya21

+0

さて、それは500行に似ていますが、私のユーザはそれを具体的に求めています:/ さらに、月間/年ごとにデータを表示しているので、リストにはブラウジング機能があります。ユーザpov。 –

答えて

0

改ページした場合、定期的な要求などは、その後除外される...

あなたは、UIにバインドされていない1配列内のすべてのデータを持つことができます。 次に、uiにバインドされている2番目の配列にデータを定期的に追加します。既に述べたように、あなたはすでにそれをやっていますが、チャンクを$タイムアウトまたは$間隔で追加するだけです。これにより、$ダイジェストとページレンダリングが完了します。

簡単な例:

<table> 
    <tr ng-repeat="item in shownItems track by $index"> 
    <td>{{item}}</td> 
    </tr> 
</table> 

とコントローラ

app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) { 
    //array that is bound to ui 
    $scope.shownItems = []; 
    //backing data 
    var fullItemsList = []; 
    //Create some fake data, you wouldn't do this in your program, 
    // this is where you would fetch from server 
    for(var ii = 0; ii < 50000; ii++){ 
    fullItemsList.push("AYYYLMAO " + ii); 
    } 

    //How many items to add at a time 
    var chunkSize = 500; 
    //keep track of how many we have already added 
    var currentChunkIndex = 0; 

    //transfers a chunk of items to ui-bound array 
    function addMoreItems(){ 
    var start = currentChunkIndex * chunkSize; 
    var end = (currentChunkIndex + 1) * chunkSize; 
    for(var ii = start; ii < end; ii++){ 
     if(!fullItemsList[ii]){ 
     break; 
     } 
     $scope.shownItems.push(fullItemsList[ii]); 
    } 
    currentChunkIndex++; 
    } 

    //Transfer chunk of items in a timeout, trigger another timeout to 
    //add more if there are stil items to transfer 
    function periodicAdd(){ 
    $timeout(function(){ 
     addMoreItems(); 
     if(currentChunkIndex*chunkSize >= $scope.shownItems.length){ 
     periodicAdd(); 
     } 
    },0); 
    } 
    //Add the first chunk straight away, otherwise it will wait for the 
    //first timeout. 
    addMoreItems(); 
    //Start the timeout periodic add. 
    periodicAdd(); 
}]); 

Example plunkr

でこの例は非常に荒れていることに留意してください。例えば、50k行の最初の "load"はuiスレッド上で実行されますが、データロードはおそらくサーバーから非同期になるでしょう。これはまた、要求が完了したときにのみ定期的な追加を開始する必要があることを意味します。そう、ええ、ただの大まかな例です。

私は0ミリ秒のタイムアウトを使用することに注意してください。これはコールバックを現在の処理キューの最後にプッシュしますが、0ミリ秒にもかかわらず直ちに実行されません。あなたのアプリケーションに呼吸の部屋のビットを与えるために少し増やしたいかもしれません。タイムアウトを適切に処分することを忘れないでください。

+0

ありがとうございました!まさに私がやろうとしたことです。私は$タイムアウトの振る舞いを知っていることに気づいていませんでした。 –

+0

$ timeoutで問題が発生しました。関数の初期化時に$ timeoutが呼び出され、要求が終了する前にループが開始されるようです。 $ intervalを使用して修正しましたが、何が起こっているのか誤解しているかもしれませんが、このようにうまくいきます。 –

+0

はい私の答えでは、私の例ではロードがすぐに開始されたと言いましたが、あなたのコードでは、 –

0

サーバーサイドページネーションを使用します。ワンタイムバインディングを使用しても、特に複雑なテンプレートロジック(データプロパティに応じて部分を表示/非表示)があり、編集が必要な場合は、常に解決策ではありません。

いくつかの基準(月、年など)で配列をフィルタリングする場合は、これをバックエンドに実装し、サーバーに基準を渡します:GET /my_data?year=2017&month=7&page=1

関連する問題