Jak wymusić ponowne renderowanie komponentu w Angular 2? Do celów debugowania, pracując z Redux, chciałbym zmusić komponent do ponownego renderowania widoku, czy to możliwe?
angular
angular2-changedetection
born2net
źródło
źródło
Odpowiedzi:
Renderowanie następuje po wykryciu zmiany. Aby wymusić wykrywanie zmian, aby wartości właściwości komponentów, które uległy zmianie, były propagowane do modelu DOM (a następnie przeglądarka wyrenderuje te zmiany w widoku), oto kilka opcji:
$rootScope.$digest()
- tzn. Sprawdź pełne drzewo komponentów$rootScope.$apply(callback)
- tzn. Ocenia funkcję callback w strefie Angular 2. Myślę, ale nie jestem pewien, czy kończy się to sprawdzaniem pełnego drzewa komponentów po wykonaniu funkcji zwrotnej.$scope.$digest()
- tzn. Sprawdza tylko ten składnik i jego dzieciTrzeba będzie importować, a następnie wstrzyknąć
ApplicationRef
,NgZone
alboChangeDetectorRef
do swojego urządzenia.W przypadku twojego konkretnego scenariusza zalecałbym ostatnią opcję, jeśli zmienił się tylko jeden komponent.
źródło
this is the first time I am facing an update not working in ng2
. Strategia wykrywania zmian jest domyślna, więc wiem, że nie zepsułem strategii wykrywania zmian.this
kontekstu w wywołaniu zwrotnym POST.pure:false
w rurze. Działa, ale jest zbyt drogi (nieefektywny) dla mojego przypadku użycia.tx, znalazłem obejście, którego potrzebowałem:
Running zone.run wymusi ponowne renderowanie komponentu
źródło
Podejście ChangeDetectorRef
źródło
Wymuszam ponowne załadowanie komponentu za pomocą * ngIf.
Wszystkie komponenty w moim kontenerze wracają do haków pełnego cyklu życia.
W szablonie:
Następnie w pliku ts:
źródło
setTimeout()
. Teraz mój pracuje z prostym i lekkim rozwiązaniem!Inne odpowiedzi tutaj zawierają rozwiązania do wyzwalania cykli wykrywania zmian, które aktualizują widok komponentu (co nie jest tym samym, co pełne ponowne renderowanie).
Pełna re-render, który zniszczy i ponownie zainicjować składnik (nazywając wszystkie haki cyklu życia i odbudowy widok) mogą być wykonane przy użyciu
ng-template
,ng-container
aViewContainerRef
w następujący sposób:Następnie w komponencie mającym odniesienie do obu
#outlet
i#content
możemy wyczyścić zawartość outletów i wstawić kolejną instancję komponentu potomnego:Dodatkowo początkową treść należy wstawić na
AfterContentInit
hook:Pełne działające rozwiązanie można znaleźć tutaj https://stackblitz.com/edit/angular-component-render .
źródło
ChangeDetectorRef.detectChanges()
jest zwykle najbardziej skoncentrowanym sposobem na zrobienie tego.ApplicationRef.tick()
jest zwykle zbyt dużym podejściem do młota kowalskiego.Aby go użyć
ChangeDetectorRef.detectChanges()
, potrzebujesz tego u góry swojego komponentu:... wtedy zwykle nazywasz to aliasem, kiedy wstrzykujesz to w konstruktorze w ten sposób:
constructor( private cdr: ChangeDetectorRef ) { ... }
Następnie w odpowiednim miejscu nazywasz to tak:
To, gdzie dzwonisz,
ChangeDetectorRef.detectChanges()
może mieć duże znaczenie. Musisz w pełni zrozumieć cykl życia i dokładnie jak działa Twoja aplikacja i renderuje jej komponenty. Nic nie zastąpi tutaj całkowitego odrabiania pracy domowej i upewnienia się, że rozumiesz cykl życia Angular na wylot. Następnie, gdy już to zrozumiesz, możesz używać goChangeDetectorRef.detectChanges()
odpowiednio (czasami bardzo łatwo jest zrozumieć, gdzie należy go użyć, innym razem może to być bardzo złożone).źródło