Cześć, temat dotyczy angulara.
Mam w widoku komponenta pętlę *ngFor, która wypełnia elementy grida bootstrapowego. Teraz kwestia jest tego typu, ze elementy te załadowane są w pliku ts do tablicy, a zawartość tej tablicy może się zmieniać - elementy mogą do niej dochodzic, bądź ubywać z niej. Chciałbym w jakiś sposób odświeżać grida po zmianie zawartości tablicy. Próbowałem markForCheck(), ale nie zadziałało. Jakieś sugestie jak by to można dobrze zrobić?
Poczytaj o https://angular.io/api/core/OnChanges
A po zmianie elementów tablicy angular nie aktualizuje automatycznie zawartości grida ?
To jest co najmniej dziwne, bo u mnie działa normalnie. https://stackblitz.com/edit/angular-2hnndg?embed=1&file=src/app/app.component.html
Nowe elementy dochodzą do tablicy jeżeli mi coś przyjdzie w .subscribe - może to ma jakieś znaczenie?
Jeśli iterujesz w ngFor bezpośrednio po elementach tablicy do której dodajesz dane to nie. A w konsoli nie masz błędów ?
marcin82w napisał(a):
Jeśli iterujesz w ngFor bezpośrednio po elementach tablicy do której dodajesz dane to nie. A w konsoli nie masz błędów ?
Faktycznie, był błąd, nie zauważyłem go. Poprawiłem i działa. Mam jeszcze jedno pytanie - bo w sumie problem jest taki, że ten *ngFor w widoku na początku życia komponentu nie ma danych i sypie błędami. Jak by można było poczekać na te wyniki, które przyjdą z subscribe'a?
Ale jeśli tablica będzie pusta to nie będzie iterował, w konstruktorze tylko zainicjuj tą tablicę. np
data= []
Zainicjowałem, ale to nie pomogło jako tako, sypie błędami, dopiero jak zrefreshuję stronę to elemety się ładują.
A jak dodajesz elementy do tablicy ? Async pipe nie możesz użyć ?
Jakbyś kawałek kodu pokazał łatwiej było by podpowiedzieć.
marcin82w napisał(a):
A jak dodajesz elementy do tablicy ? Async pipe nie możesz użyć ?
W komponencie mam tablice items = new Array<Item>(); i później w ngOnInit mam .subscribe, gdzie po otrzymaniu danych robię this.items.push(dana_ktora_przyszla). Nie stosowałem prędzej async pipe- nie wiem czy się nada w tym przypadku? Bo próbowałem w ngFor dodać "| async", ale zarzuciło błędami.
Dodaj, tylko nie rób subscribe w ngOnInit. Async pipie zadba o resztę.
marcin82w napisał(a):
Dodaj, tylko nie rób subscribe w ngOnInit. Async pipie zadba o resztę.
No tylko, że ten mój subscribe, który zbiera dane umieściłem w ngOnInit i wygląda mniej więcej tak:
public ngOnInit(): void {
this.subscription = this.dTService.initialized.subscribe((change: DSChange) => {
change.added.forEach((item: Item) => {
this.items.push(item);
});
change.changed.forEach((item: Item) => {
this.items.push(item);
});
});
}
Więc teraz pytanie co z tym zrobić, skoro mówisz, żeby nie robić subsribe w ngOnInit?
A to tego nie zrobisz poprzez async pipe. Rozumiem że w ngFor iterujesz po items. W konstruktorze próbowałeś inicjować poprzez
this.items = []
?
Wszystko rób przez async pipe. Poczytaj o deklaratywnym podejściu w angularze. Ogólnie chodzi o to, że masz w pipie tak przekształcić dane, że jak walniesz subscribe(np async pipem) to dane są gotowe, to ma wiele zalet, m.in można użyć ChangeDetection.ON_PUSH ale także nie trzeba samemu robić unsubscribe