Nie bardzo rozumiem, dlaczego muszę dodać markForCheck () do poniższego kodu, aby zmiany były widoczne. Dlaczego moja @Input () nie wyzwala wykrywania zmian?

Refaktoryzuję swój projekt do OnPush. Te 2 składniki mają włączoną funkcję OnPush. Jak rozumiem, kiedy ta opcja jest włączona, a Input () zostanie zmieniona (jak messages), wyzwalane jest wykrywanie zmian.

W poniższym kodzie dzwonię przez graphqlService. Kiedy otrzymuję wywołanie, analizuję dane przychodzące, a następnie ustawiam je na właściwość informationMessages, która jest powiązana z komponentem potomnym cv-messages poprzez jego właściwość messages.

W rezultacie funkcja ngOnChanges jest wywoływana tylko raz, kiedy właściwość informationMessages zostanie zainicjowana. Ale nie wtedy, gdy ustawiono na niego końcowe przeanalizowane dane.

Jeśli dodam markForCheck (), to działa dobrze.

Rozważmy ten komponent nadrzędny z takim szablonem:

<cv-messages [messages]="informationMessages"></cv-messages>

Oraz plik maszynopisu z tym fragmentem kodu:

informationMessages: InformationMessageType[] = [];

ngOnInit() {
    this.graphqlService.loadInformationMessages().subscribe(data => {
        const informationMessages: InformationMessageType[] = data;

        .... // parsing stuff

        this.informationMessages = informationMessages;
        // add markForCheck() here
    });
}

Komponent wiadomości ma następującą funkcję ngOnChanges:

ngOnChanges(changes) {
    console.log(this.constructor.name ' CHANGE:', changes);
}

Aktualizacja:

Rozwiązanie znajdziesz w komentarzach do odpowiedzi poniżej. Zasadniczo wykrywanie zmian NIE jest wyzwalane, gdy @Input() zmienia się asynchronicznie. W takim przypadku musimy dodać markForCheck(), aby wymusić wykrycie zmiany.

4
Martijn van den Bergh 9 grudzień 2019, 11:56

1 odpowiedź

Najlepsza odpowiedź

Jak mówi dokumenty kątowe:

Gdy widok używa strategii wykrywania zmian ONPUSH (Checkonce), wyraźnie oznacza widok, jak zmienił się tak, że można je ponownie sprawdzić.

Składniki są zwykle oznaczone jako brudne (wymagające renantów), gdy wejścia się zmieniły lub zdarzenia zostały zwolnione w widoku. Wywołaj tę metodę, aby zapewnić sprawdzenie, że składnik jest sprawdzany, nawet jeśli wyzwalacze nie wystąpiły.

Więc ta metoda jest potrzebna do oznaczenia komponentu jako brudna, aby być nerwowym.

AKTUALIZACJA:

Istnieją dwa typy ChangeDetectionStrategy:

onpush: 0 Użyj strategii Checkonce, co oznacza, że Automatyczne wykrywanie zmian jest wyłączone strategia domyślna (kontrole). Wykrywanie zmian może być nadal wyraźnie wywołany. Ta strategia ma zastosowanie do wszystkich dyrektyw dziecka i nie może być zastąpiony.

Domyślnie: 1 Użyj domyślnej strategii kontrolnej, w którym wykrywanie zmian jest automatyczne wyłączone, aż wyraźnie wyłączono.

Więc kiedy używasz OnPush, a następnie Automatyczne wykrywanie zmian jest wyłączone i konieczne jest, aby zaznaczyć widok jako zmieniony tak, że można je ponownie sprawdzić.

5
StepUp 9 grudzień 2019, 09:25