Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewChild vs Input/Ouput - Angular Best Practices [closed]

Tags:

angular

It seems to me that in almost all cases where we specify component @Inputs/@Outputs we could alternatively not have any @Inputs/@Outputs but instead use @ViewChild to access component properties directly. For example, consider these two possible APIs for a pager:

Option 1: Expose current page and total pages as @Inputs, make event emitters (@Outputs) for the next/previous page requests.

<pager 
    [currentPage]="..." 
    [totalPages]="..." 
    (requestsNextPage$)="..." 
    (requestsPreviousPage$)="..."
></pager>

Option 2: Make simple properties for current page and total pages, make observables/subjects for next/previous page requests and expose via @ViewChild.

<pager></pager>

@ViewChild(PagerComponent)
pager: PagerComponent

pager.currentPage = ...
pager.totalPages = ...

pager.requestsNextPage$.subscribe(...)
pager.requestsPreviousPage$.subscribe(...)

My question is, if both of these options are equally possible in most cases, what is the preferred/best practice and why?

like image 849
peter554 Avatar asked Mar 08 '19 18:03

peter554


People also ask

Should we use ViewChild?

The @ViewChild decorator allows us to inject into a component class references to elements used inside its template, that's what we should use it for. Using @ViewChild we can easily inject components, directives or plain DOM elements.

What is the difference between output and ViewChild in Angular?

While Angular inputs/outputs should be used when sharing data to and from child components, ViewChild should be used when trying to utilize properties and methods of the child component directly in the parent component.

What is the purpose of ViewChild in Angular?

ViewChild makes it possible to access native DOM elements that have a template reference variable. Whale! The parent component was able to set the value of the child DOM Element.

For what do you use input and output in Angular?

@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.


1 Answers

The two situations you describe are not equivalent.

Situation A:

<child [property]="value"></child>

The child component will be rendered with "property = value" and whenever "value" changes, the child component's view will be updated (because an input property changed).

Situation B:

<child></child>

child.property = value;

The child component is rendered with "property = value" (depending when in the lifecycle this code runs) and further changes will NOT be reflected in the child component's view.


If you're just setting an initial value that never changes, then it may be possible for these two situations to be equivalent. However, that's unlikely to be what you want to do. Angular is very aggressive about re-using components, and one of the criteria it uses is the @Input properties. I have run into trouble where a component was reused instead of deleted and re-created due to this behavior, and it can be very frustrating to understand and debug.

like image 95
Vlad274 Avatar answered Oct 12 '22 19:10

Vlad274