I've been reading alot and to be honest haven't seen any meaningful solution. So i have a component which contains a button and a dropdown to display some content (another buttons in this scenario).
Kebab button component:
<button>some button displaying dropdown<button>
<app-dropdown-component>
<ul>
<ng-content></ng-content>
</ul>
</app-dropdown-component>
It looks like this. As ng-content i'm providing a list items in a different components. The thing is that i want to hide this button when no list items are provided. Have tried using #ref on a item and then
@ViewChild('ref') items: ElementRef;
and then check in ngAfterViewInit
this.showButton = this.items.nativeElement && this.items.nativeElement.children.length > 0
also with .detectChanges();
but it usually says 'cannot read property 'nativeElement' of undefined. Is there any simple way to hide my button when there are no elements provided by ng-content? Also i can't use *ngIf on my button so looking for a different way. I could also accept an solution from a children perspective:
<app-kebab-button-component>
<li *ngIf="something">Something</li>
</app-kebab-button-component>
So i show kebab-button-component only if there is any <li>
provided due to a *ngIf statement.
Im running angular 12
CodePudding user response:
You could handle this with CSS:
app-dropdown-component{
display: flex;
flex-direction: column-reverse;
}
app-dropdown-component ul:empty ~ button {
display: none;
}
While reversing the order of the items and button with display: flex
and flex-direction
as row-reverse
or column-reverse
.
<app-dropdown-component>
<ul>
<ng-content></ng-content>
</ul>
<button>some button displaying dropdown<button>
</app-dropdown-component>
CodePudding user response:
You have to name your ng-content component:
<ng-content #ref></ng-content>
Otherwise ViewChild doesn't know what it's looking for.
Personally, I avoid ViewChild whenever possible. Instead attach the *ngIf to the data that the content is bound to:
<button *ngIf="items.length > 0">
<div *ngFor="let item of items">{{item}}</div>
Hope that helps.