@ViewChild służy do pobrania referencji elementu z szablonu. Jego standardowe wykorzystanie może wyglądać tak:
@Component({selector:'app-root',standalone:true,template:`
<div #rightClickMenu>
Click me right. Counter:
</div>
`,})exportclassPlaygroundComponentimplementsAfterViewInit{@ViewChild('rightClickMenu')rightClickMenu!:ElementRef;counter=signal(0);ngAfterViewInit(){this.rightClickMenu.nativeElement.addEventListener('contextmenu',(event:MouseEvent)=>{event.preventDefault();this.counter.set(this.counter()+1);});}}
Podczas wykorzystania @ViewChild zmienna przechowująca referencję jest uzupełniana dopiero po zainicjowaniu widoku.
Dlatego TypeScript dla takiego przypadku wymaga określenia dodatkowego typu undefined lub wyłączonej non-null asercji.
Angular 17.2 wprowadził metodę viewChild, która zwraca referencję w postaci sygnału.
W wersji z viewChild powyższy komponent wygląda następująco:
@Component({selector:'app-root',standalone:true,template:`
<div #rightClickMenu>
Click me right. Counter:
</div>
`,})exportclassPlaygroundComponent{rightClickMenu=viewChild.required<ElementRef>('rightClickMenu');counter=signal(0);constructor(){effect(()=>{this.rightClickMenu().nativeElement.addEventListener('contextmenu',(event:MouseEvent)=>{event.preventDefault();this.counter.set(this.counter()+1);});});}}
Sygnałowe podejście poprawia czytelność kodu i upraszcza rozwiązanie. W drugim przykładzie zamiast AfterViewInit została użyta sygnałowa funkcja effect, aby wykonać działanie na elemencie w momencie, gdy jego referencja zostanie zwrócona przez sygnał.
W tej sytuacji można używać również funkcji computed(), aby wyprowadzać wartości z sygnału.
Dodatkową zaletą jest możliwość użycia metody required, która wymusza obecność żądanego elementu w szablonie komponentu, dlatego warto ją stosować dla statycznie zdefiniowanych elementów, aby ograniczyć konieczność stosowania dodatkowych asercji.
W sygnałach odpowiednikami dekoratorów @ViewChildren, @ContentChild i @ContentChildren są metody viewChildren(), contentChild() i contentChildren().