Angular - When should I use child components over passing an @input

290 Views Asked by At

My team and I are currently making a component library using Angular (v8.x). We want to establish some house keeping rules and keep our component interfaces intuitive (ie. consistent naming of inputs and usage of patterns).

We have found between us two schools of thoughts around using @Inputs and nesting components.

Our delema can be described using the following (watered down) examples

Example component 1:

<our-component [hideChild]="childHidden"></our-component>

Example component 2:

<our-component>
  <our-child-component></our-child-component>
</our-component>

In example 1, the component has an @Input which shows and hides the child component hard coded in the template.

In example 2, the component is added (or not) as a child (via ngContent).

I am trying to find an assertation which dictates when to use one pattern over the other. I understand there may not be one. My current thinking is that if your component has n number of children, or n numbers of types of children, use component nesting. If the component will only ever have a single type of child use an input, and include your child component inside your parent components template.

I've checked the angular style guide, but can't find anything specific to this problem.

Does anyone know of any resources or has had experience making this distinction? I'd like to hear how and why you implemented it one way or the other.


Edit: Specifically, I would like endings to the following statements:

"Use @Inputs over nested components when ..." and "Use nested components over @Inputs when ..."


Edit 2: Appreciate I may not be expressing myself properly. With our component library, among other components, we are wrapping existing angular material components such as mat-input. We have a component that wraps the mat-form-field, mat-hint and mat-input components in our template. Our component looks like this:

<our-input
 [hideAssistiveText]="hideAssistiveText"
 [type]="inputType"
 [hint]="hint"
 [label]="label"
 [control]="control"
 ... and so on
 ></our-input>

There are use cases for this component where we don't want the hint to show. So, so long as you provide the hint string, our-input will show the our-hint component (which is nested inside the template).

But I could just as well have implemented the component to work like this:

<our-input
 [hideAssistiveText]="hideAssistiveText"
 [type]="inputType"
 [label]="label"
 [control]="control"
 ... and so on
 >
   <our-hint label="{{hint}}"></our-hint>
</our-input>

And the developer could just omit the our-hint component altogether to achieve the same thing.

What I'm after is some clear cut best practice resources around when to use one method over the other (if there is any) or reasons behind which method you have adopted.

2

There are 2 best solutions below

4
On

I feel there are two schools of thoughts here. One is how your components are being organized to structure your app and how you are managing their visibility toggling. Think there should a clear separation while addressing the two.

2
On

From my experience there are a couple of cases where I would recommend Example component 1 over Example component 2.

  1. There are other inputs and outputs that the parent will pass to the child (or there could be at some point in the future).
  2. As you mentioned in your post, when the parent will always have the same child component and is not meant to support other types of children.

Example component 2 is better in cases where the parent is meant to be generic and able to have a variety of children (or could at some point in the future).

Other than that, there are no hard rules and this mostly comes down to personal preference. Either way, always consider how you may scale and use the component in the future.