2016-03-14 10 views
8

Mam problem z ngOnChange. Mam następujący komponent:Jak radzić sobie z wejściami asynchronicznymi w komponentach?

@Component({ 
    selector:'user-table', 
    template: `...`, 

}) 

export class UserTable implements OnChanges{ 
    @Input() users: User[]; 
    years:string[]; 
    constructor(private _usersCollection:UsersCollection){ 
    } 

    ngOnChanges(){ 
    if (this.users.length) 
     {this.years =this._usersCollection.createYearsArray(this.users)} 
    } 
} 

Jednakże, jeśli warunek zostanie sprawdzone tylko raz - gdy this.users nie jest jeszcze pobierany z serwera, a tym samym jego długość wynosi 0. W jaki sposób mogę znaleźć rozwiązanie do czynienia z tego rodzaju async wejścia?

Tablica jest aktualizowany, a kiedy ustawić następujące dzienniki:

console.log('ON FIRST INIT' , this.programs); 
    this.years = this._usersCollection.createYearsArray(); 
    console.log(this.years); 
    setInterval(()=>{ 
     console.log('IN INTERVVAL' , this.programs); 
    },1000); 

Wyjście konsola jest:

ON FIRST INIT [] 
UsersTable.component.ts:21 [] 
UsersTable.component.ts:23 IN INTERVVAL [Object, Object, Object, Object] 
+0

Trudno zobaczyć z tego kodu, co się dzieje. Gdzie pobierasz dane. W jaki sposób są przekazywane do komponentu 'UserTable'? –

+0

Jestem w samochodzie - zaktualizuję q w 30 ':) – uksz

Odpowiedz

7

Jeśli nie musisz wykonywać żadnej logiki, gdy zmienia się właściwość wejściowa (np. Korzystasz tylko z właściwości w powiązaniach szablonów), nie musisz nic robić. Angular automatycznie będzie propagować nowe wartości z rodzica do właściwości wejściowej.

Jeśli chcesz wykonać logikę komponentu, gdy właściwość wejściowa ulegnie zmianie, użyj ngOnChanges(), która jest wywoływana za każdym razem, gdy zmieni się właściwość wejściowa komponentu.

Ponieważ kątowa wykorzystuje === do wykrywania zmian (no, istnieje jakiś specjalny sposób postępowania dla NaN też), oznacza to, że

  • dla typów referencyjnych (array, obiekt, data, itp), odniesienia (tj , odwołanie do tablicy, obiektu itp.) musi się zmienić. Np., myArray = someNewArray;
    Jeśli zmienia się tylko element w tablicy, ngOnChanges() nie jest wywoływane. Np. W przypadku zmiany takiej jak myArray[0].name = newName;, ngOnChanges() nie jest wywoływana.
  • dla typów pierwotnych (liczba, boolean, string), oznacza to po prostu, że wartość musi się zmienić. E.g, myNumber = 5; lub myNumber = newNumber;

Inną opcją jest zaimplementować własną logikę wykrywania zmian używając ngDoCheck(). Zobacz przykład this answer. Ten hak cyklu życia jest nazywany "za każdym razem, gdy sprawdzane są właściwości wejściowe komponentu lub dyrektywy, użyj go, aby rozszerzyć wykrywanie zmian, wykonując niestandardową kontrolę" - od lifecyle hooks.md

+0

Czy powinno to zostać wykryte przez Object.assign (this.users, success.json())? – uksz

+0

@uksz, 'Object.assign() 'nie tworzy nowej tablicy, modyfikuje istniejącą tablicę' this.users'. Tak więc 'ngOnChanges()' nie zostanie wywołane. –

+0

Świetnie, dzięki! więc to był rzeczywiście problem. Btw, jak się dowiedziałeś o wykryciu zmiany w kanale kątowym2? Czytałem ngbook2 i niewiele o tym wspomniano. – uksz

0

ngOnChanges() jest wywoływana gdy users są aktualizowane. Trzeba tylko upewnić się, że nowa tablica jest przypisana users w składniku macierzystym, zamiast wypełniać istniejącą tablicę. W przeciwnym razie wykrywanie zmiany Angulars nie rozpozna zmiany.

+0

W rzeczywistości tablica zostanie zmieniona. Zmieniono moje pytanie za pomocą kilku kolejnych dzienników konsoli. – uksz

+0

Czy warto używać settera na @ Input, gdy mam wiele wejść asynchronicznych i inną logikę do wykonania? Funkcja ngOnChanges() działałaby dobrze, ale muszę sprawdzić, która właściwość uległa zmianie. – Gambo

+0

Nie jestem pewien bez szczegółowych informacji o tym, co próbujesz osiągnąć. Jeśli twoja logika zależy od wielu zmiennych, zmiana 'ngOnChanges' może być w niektórych przypadkach wygodniejsza, ale poza tym uważam, że seter jest zwykle wygodniejszy. –

Powiązane problemy