2016-06-19 2 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> 

10.000, 어쩌면 20.000 행 및 약 10 열이있는 테이블. 여기서 문제는로드가 매우 느리고로드 후에 끔찍한 지연으로 실행된다는 것입니다.

이 경우 페이지 매김을 사용할 수 없으며 스크롤은 필수입니다. 스크롤 엄지 크기와 위치를 유지하고 싶습니다. 마치 데이터의 일부만로드하는 것처럼 트릭을해야하는 경우에도 모든 데이터가로드되는 것처럼 배치하십시오.

나는 속도 저하없이이 작업을 수행하는 가장 좋은 방법이 무엇인지 알고 싶습니다.

답변

1

언급했듯이 브라우저의 많은 양의 데이터를 요청하고 다운로드해야하기 때문에 이것은 상당히 많은 양의 데이터이며 사용자에게 비용이 많이 듭니다.

데이터를 하위 섹션으로 나누고 페이지 매김을 추가하는 것이 좋습니다. 페이지 당 약 100 개의 레코드 만 표시하십시오. 가독성과 사용자 경험을 향상시킵니다.

각도 1.x.x에서는 limitTo 필터를 사용하여 결과를 제한 할 수 있습니다. Angular 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> 

구성 요소

은 또한 당신이 infinite scrolling의 형태를 사용할 수있는이

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 
    } 
} 

처럼 보일 것입니다.

+0

페이지 매김은 내 생각 이었지만 불행히도 내 상사는이 작업에 페이지 매김을 원하지 않습니다. 페이징 (pagination)이란 각 페이지에 대한 링크가 부트 스트랩 페이지 매거진 (bootstrap paginator) 또는 귀하의 예처럼 테이블 아래에 있음을 의미합니다. 실제로 필자는 요구에 따라 데이터를로드해야하지만 페이 지 네이터가 아닌 스크롤을 사용해야합니다. 1000 행을 시도하고 원활하게 실행됩니다. 5000 아닙니다. 무한 스크롤과 비슷한 것이 필요하지만 사용자는 스크롤 썸을 사용하여 테이블의 일부 부분으로 이동할 수 있어야합니다. – Natanael

+0

작은 부분이 빠졌음에도 불구하고 나는 접근법을 좋아합니다. 그럼에도 불구하고 좋은 출발점. 'ngx-bootstrap'으로 큰 병합 :-) – LeO

4

테이블을 구성 요소로 변환하고 변경 감지 전략을 "적용"으로 변경하는 것이 좋습니다. 그런 식으로 Angular는 성능 비용을 줄입니다.

0

조금 늦었지만 나는 다른 사람들이 오는 것을 도울 수 있기를 바랍니다.
일부 변경 사항이있는 Richard Hamilton의 페이지 매김 예제를 사용하고 있습니다.

또는 무한대 스크롤을 사용할 수 있습니다.

 <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

관련 문제