I was looking for ways to create a dynamic menu where we get list of menu items from the api and I came across this stackoverflow question
This explains how to use ngTemplateOutlet
to call your own custom template to populate the menu item by referencing the same template again.
if you have an array of menuItems
like this:
menuItems: MenuItem[] = [
{
label: 'Home',
href: '/home',
},
{
label: 'Articles',
href: '/articles',
children: [
{
label: 'News',
href: '/articles/news',
},
{
label: 'Entertainment',
href: '/articles/entertain',
},
],
},
{
label: 'About',
href: '/about',
},
];
I have used hardcoded value for menuItems
but this can be populated by getting the value from the api.
So, on the HTML (view of the component) we only have to do is:
<nav>
<ul class="navigation-list">
<ng-template #menuItemTemplate let-items>
<li *ngFor="let item of items">
<a href="{{item.href}}">{{item.label}}</a>
<ng-container *ngIf="item.children">
<ul class="sub-menu">
<ng-container *ngTemplateOutlet="menuItemTemplate;
context: { $implicit: item.children }">
</ng-container>
</ul>
</ng-container>
</li>
</ng-template>
... more code will go here
</ul>
</nav>
Above, we have created our custom template using <ng-template>
that creates a reference menuItemTemplate
. The let-items
inside the ng-template tag creates a variable that will be replaced by the $implicit
value that we define inside the context
of ngTemplateOutlet
. Now, whenever a menu item has it's children then it will create the template by passing in the item.children
array.
But how do we actually use the menuItems
that we created on the component? We just have to call the template again by simply replacing ... more code will go here
with
<ng-container *ngTemplateOutlet="menuItemTemplate; context: { $implicit: menuItems }"></ng-container>
by using the actual value of menuItems
.
And that's it. You will have your nested menu items, no matter how many children the menuItems
will hold.
Would love to know more ways that you could create dynamic menus! please drop in on the comments
P.S: the menu is not styled so feel free to use your imagination :p
Top comments (0)