2016-06-19 3 views
2

私は大量のデータをスクロール可能な テーブルに表示する必要があるAngular 2アプリを開発しています。角度2を使用して大量のデータをテーブルにロードして表示する方法はありますか?

データは私のコンポーネントクラスの配列である:

export class AppComponent { 

    clients: any[] = []; 

    constructor(){ 
     for (var i = 0; i < 10; ++i) { 
      this.clients.push({ 
       id: i, 
       name: 'Client' + i, 
       address: 'Address of client ' + i, 
       phone: '(51) 5454-4646' 
      }); 
     } 
    } 
} 

そしてデータが私のレイアウトでngFor介してロードされる:例えば

 <div style="height:600px;overflow:scroll"> 

      <data-table> 

      <th>Id</th> 
      <th>Name</th> 
      <th>Address</th> 
      <th numeric>Phone</th> 

      <tr *ngFor="let client of clients"> 
      <td>{{ client.id }}</td> 
      <td>{{ client.name }}</td> 
      <td>{{ client.address }}</td> 
      <td>{{ client.phone}}</td> 
      </tr> 

     </data-table> 
     </div> 

、それはAのデータをロードする必要があります10.000、おそらく20.000行、およそ10列のテーブル。ここで問題となるのは、ロードが非常に遅く、ロード後にひどいラグで実行されるということです。

私はこのケースで改ページを使用することはできませんし、スクロールは必須です。私は、データの一部だけをロードするようなトリックを行う必要がある場合でも、すべてのデータがロードされているかのようにスクロールサムのサイズと位置を保持したいと思います。

私が速度低下なしでこの作業を行うための最良のpraticceが何であるかを知っていただきたいと思います。

答えて

1

あなたが言及したように、これはデータのかなり多くあると、ブラウザのは、大量のデータを要求し、ダウンロードする必要がありますようユーザーに高価になるだろう。

私は、サブセクションにダウンしたデータを破壊し、改ページを追加することをお勧めします。 1ページあたり約100件のレコードしか表示しない。読みやすさとユーザーエクスペリエンスが向上します。角度1.x.xで

、あなたは結果を制限するためにlimitToフィルタを使用することができます。角度2.x.xでは、sliceフィルタを使用できます。

更新されたテンプレートは、次のようになります。私はこれが動作することを保証することはできませんが、それは基本的なアプローチを示します。

 <th>Id</th> 
     <th>Name</th> 
     <th order="desc">Address</th> 
     <th numeric>Phone</th> 
     <th>Ações</th> 

     <tr *ngFor="let client of clients | slice:pageStart:100"> 
     <td>{{ client.id }}</td> 
     <td>{{ client.name }}</td> 
     <td>{{ client.address }}</td> 
     <td>{{ client.phone}}</td> 
     <td>Ações</td> 
     </tr> 

     <button *ngIf="pageStart >= 100" (click)="prevData()">Previous</button> 
     <button *ngIf="pageStart < clients.length" (click)="NextData()">Next</button> 
    </data-table> 

コンポーネントは、この

export class DataTable { 
    // Code omitted for brevity 
    pageStart = 0; 

    nextData() { 
    this.pageStart += 100;   // Get the next 100 records 
    } 

    prevData() { 
    this.pageStart -= 100;   // Get the previous 100 records 
    } 
} 

代わりにあなたがinfinite scrollingのいくつかのフォームを使用することができようになります。

+0

ページネーションは私の最初のアイデアでしたが、残念ながら私の上司はこの作業のページングを望んでいません。ページネーションとは、あなたの例では、ブートストラップ改行のような表の下の各ページへのリンクを意味します。実際、私は要求に応じてデータを読み込まなければならないが、ページャーではなくスクロールを使用しなければならない。私は1000行を試して、それはスムーズに実行されます。 5000無し。無限スクロールに似た何かが必​​要ですが、ユーザーはスクロールサムを使ってテーブルのある部分にジャンプできなければなりません。 – Natanael

+0

私は小さな部品が欠けていましたが、アプローチが気に入っています。それにもかかわらず、良い出発点。 'ngx-bootstrap'で大いにマージされました:-) – LeO

4

私はコンポーネントにあなたのテーブルを変換することができrecomandだろう、と「プッシュオン」に変化検出戦略を変更します。 そのようにAngularはパフォーマンスコストを削減します。

0

少し遅れていますが、私は他の人が来るのを助けてくれることを願っています。
リチャード・ハミルトンのページ変更の例をいくつか変更して使用しています。

また、何らかの形の無限スクロールを使用することもできます。

 <div style="height:600px;overflow:scroll" (scroll)="onScroll($event)"> 

     <data-table> 

     <th>Id</th> 
     <th>Name</th> 
     <th>Address</th> 
     <th numeric>Phone</th> 

     <tr *ngFor="let client of clients | slice:pageStart:pageEnd"> 
     <td>{{ client.id }}</td> 
     <td>{{ client.name }}</td> 
     <td>{{ client.address }}</td> 
     <td>{{ client.phone}}</td> 
     </tr> 

    </data-table> 
    </div> 

唯一の違いは、スクロールのEventListenerと無改ページボタンです。

export class DataTable { 
    pageStart:number = 0; 
    pageEnd:number = 100; 
    pageHeight:number = 30; 
    pageBuffer:number = 100; 

    onScroll(event, doc) 
    { 
    const scrollTop = event.target.scrollTop; 
    const scrollHeight = event.target.scrollHeight; 
    const offsetHeight = event.target.offsetHeight; 
    const scrollPosition = scrollTop + offsetHeight; 
    const scrollTreshold = scrollHeight - this.pageHeight; 
    if(scrollPosition > scrollTreshold){ 
     this.pageEnd+= this.pageBuffer; 
    } 
    } 
} 

スクリプトは位置を確認し、最後に到達するまでpageEndを調整します。
ある時点で、この解決策も遅くなります。

私は無限のスクロールソリューションしか必要としませんでした。だから私は、スローダウンの問題なしに解決策について私の考えを伝えることができます。

この問題を防ぐには、rowHeightが固定されていることを確認する必要があります。
これですべての行の最大高さを計算できます。
追加要素を高さで作成して、スクロールできることを確認します。
設定位置:固定;データテーブルに保存する。
これにより、テーブルが常に表示されます。
pageStartとpageEndの位置を計算します。
スライスがレンダリングを行います。

これはうまくいくと思いますが、まだテストしていません。 これは毎日の使用に適したソリューションであるかどうかもわかりません。

まあまあです。 :)

+0

こんにちは、私はあなたのソリューションを使用して、私は問題に直面しているこのhttps://stackoverflow.com/q/47903845/8632727に助けることができます – Patata

関連する問題