fortuneNext
fortuneNext

Reputation: 129

Angular: Boolean @Input vs Attribute @Directive - which to use?

What I want to do using Angular is to create a "directive" that adds a something to my component, lets say a myPortlet with myHasCloseButton gives myPortlet a close button.

<myPortlet myHasCloseButton>...</myPortlet>

I found three options how to approach this and I'm not sure which one is the correct one or if I missed a better option.

Option 1: Create a directive that does something like

this.el.nativeElement.querySelector('.myCloseButton').style.visibility = 'visible';

Option 1a: Just like Option 1, but give the directive an boolean @Input that switches the application of the visibility.

Option 2: Give myPortlet a boolean @Input and a *ngIf directive at the right place.

Option 2b: "Hackily" give a string @Input instead and check if it's empty (as that's what happens when you just give the input name without anything after) and treat it as true.

Option 3: Create a directive that actually injects the myCloseButton via something like

ElementRef.nativeElement.querySelector('.myCloseButton').addComponent(myCloseButton)

[No actual tested Syntax, just an example, not sure if addComponent is the correct function and how to use it]

So my question is: Which is the recommended approach? Am I missing any option? Any best practices? None of those options feels right.

Upvotes: 0

Views: 963

Answers (1)

vince
vince

Reputation: 8306

Using @Input() is best for this use case.

It's simple, clean, and most importantly, it allows you to dynamically determine whether your component has a close button (a nice feature you could not get with the attribute directive). Example (this is terrible UX), but what if you only wanted to allow admin users to have a close button. Then, you could subscribe to your user service and set [hasCloseButton]="userIsAdmin$ | async". That's pretty powerful stuff you couldn't do (in a clean way) with an attribute directive.

Also, for testing, you can just set the input directly (testComponent.hasCloseButton = true), rather than having to create a test host component and create one case with the directive / one without.

To summarize: using @Input() will afford you more flexibility and make testing easier.

Upvotes: 2

Related Questions