Angular 6 - dużo danych. Generowanie tabeli z pomocą *ngFor

0

Witam.
Mam tabele z towarami. Jest ich ponad 12k. Próbuje zrobić progress bar, który będzie sygnalizował, że dane są ładowane. Problem polega na tym, że to co mam zrobione pokazuje progress bar tylko na chwilę, później się zacina, stoi w połowie i znika jak już tabela jest wygenerowana.

Domyślam się, że to co mam zrobione tyczy się pobierania danych z API, a nie samego renderowania tabeli, dlatego progress bar się zacina w połowie animacji.

  isLoading$: BehaviorSubject<boolean> = new BehaviorSubject(false);
  isZerowe: boolean = false;

  ngOnInit() {
    this.isLoading$.next(true);
    this.globals.updateGlobalKontrahent(null);
    this.api.GetTowary(this.isZerowe).subscribe((result: any[]) => {
      this.towary = result;
    }, (error) => { console.log(error) }, () => {
      this.isLoading$.next(false);
    });
  }
<div *ngIf="isLoading$ | async" class="progress active">
  <div class="progress-bar indeterminate progress-bar-danger" role="progressbar" style="width:50%; height:4px;"></div>
</div>

   <div *ngIf="!(isLoading$ | async)" class="table-responsive row">
     <table class="table table-bordered table-head-purple table-hover table-striped" width="100%" id="towaryTable">
       <thead class="thead-default thead-lg">
         <tr>
           <th>#</th>
           <th>Kod</th>
           <th>Nazwa</th>
           <th>Typ</th>
           <th>EAN</th>
           <th>Numer katalogowy</th>
           <th>JM</th>
           <th>Ilość</th>
           <th>Cena</th>
           <th>CenaPLN</th>
         </tr>
       </thead>
       <tbody>
         <tr (dblclick)="route.navigate(['/towar/edit/', t.ID])" *ngFor="let t of towary; let i = index">
           <td>{{i + 1}}</td>
           <td>{{ t.Kod }}</td>
           <td>{{ t.Nazwa }}</td>
           <td>{{ t.Typ }}</td>
           <td>{{ t.EAN }}</td>
           <td>{{ t.NumerKatalogowy }}</td>
           <td>{{ t.JM }}</td>
           <td>{{ t.Ilosc }}</td>
           <td>{{ t.Wartosc | currency:' ':'code' }}</td>
           <td>{{ t.WartoscPLN | currency:' ':'code' }}</td>
         </tr>
       </tbody>
     </table>
   </div>

Da się wyłapać moment, w którym tabela jest już wyrenderowana?

0

Może po prostu nie generuj tabeli z 12k wierszami? :-P
Rzuć okiem np. na Handsontable - radzi sobie świetnie z dużymi tabelami.

0

Bardzo mądre podejście i owszem mam pewien sposób, aby zrobić z 12k np. 500 pozycji. Problem polega na tym, że muszę dać użytkownikowi możliwość wyświetlenia wszystkich (12k). Nawet szybko się ładuje przez *ngFor, ale muszę użytkownika o tym poinformować, że ma czekać ;) Próbowałem już datatables.net, do bani totalnie. Potrzebuje tylko info o ładowaniu, więc twoja propozycja tez mi nie potrzebna, bo jak mam kupić/używać tylko po to żeby dać info, że wczytuje dane to lekko się to mija z celem :D
Zaznaczam jeszcze raz, problem nie leży w czasie ładowania danych/pobierania z API, tylko problem leży w informowaniu użytkownika, że w tym czasie się dane ładują i ma czekać ;)

1

Podczas przetwarzania DOMu (dodawania, usuwania czy modyfikowania elementów) cały event loop jest blokowany - jeśli chcesz mieć progress bar, do tablicy this.towary wrzucaj paczki po np. 1000 elementów.

0

Kontynuuje wątek, ponieważ coś mi się nie zgadza:

      let temp2:any[] = [];
      for (let i = 1; i <= loopCounter; i++) {
        let start = (i * 1000) - 1000 ;
        let end = i * 1000;
        let temp1 = tempKontrahenci.slice(start, end);
        temp2.push(temp1);
      }

Nie wiem czy dobrze to robię, pewnie nie, ale dlaczego temp2.push(temp1) nie wrzuca mi elementów tablicy temp1 tylko robi mi tablice tablic?

2

Ponieważ temp1 to tablica. Slice tworzy nową tablicę https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/slice
Możesz zrobić np coś takiego: temp2 = [...temp2, ...temp1]

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0