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

Angular 6 - dużo danych. Generowanie tabeli z pomocą *ngFor
AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
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.

Kopiuj
  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);
    });
  }
Kopiuj
<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?

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
0

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

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
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ć ;)

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
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.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

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

Kopiuj
      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?

OM
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 100
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]

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.