ng-zorro-antd
ng-zorro-antd copied to clipboard
Allow for ng-template as input for dropdown component
What problem does this feature solve?
In my use case, I create lists of items with multiple actions that you can do on them, for this I'm using the dropdown component. However, these dropdowns are always the exact same component with just the item id that's changing, creating a lot of repetition inside the DOM, leading to bad loading times when there's hundreds of these items in the screen.
If we could provide the same template, which would be used to create the menu when it's being opened, then all these menus would be combined into one, making things way lighter for the DOM.
What does the proposed API look like?
An additional input on nz-dropdown component, allowing to pass a ngTemplate
instead of a nzDropdownMenu
instance. I'm not sure how this translates in terms of code especially because of how it could make the nz-menu reference harder to get, but that's what I would imagine.
Hi @Supamiu
you are right, it would make it impossible to get nz-menu
reference under the current angular version and v9.
we need nz-dropdown-menu
to integrate with the nz-menu
now
ref https://github.com/angular/angular/issues/14842
I just had an idea about this:
What if we could pass some context to the menu directive itself? This way, it would be easier to create one common menu and have it be updated on the fly when it's being opened.
Example:
<a nz-dropdown [nzDropdownMenu]="menu" [nzDropDownData]="{itemId: 5}">
menu with data
<i nz-icon nzType="down"></i>
</a>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ng-template let-data>
<ul nz-menu>
<li nz-menu-item>My item id is: {{data.itemId}}</li>
</ul>
</ng-template>
</nz-dropdown-menu>
I think it could be done using this trick: https://stackoverflow.com/questions/42878506/angular-2-passing-html-to-ng-content-with-bindings.
This way, the reference isn't lost and the menu always exists, but its content is not cloned accross several rows if the menu is repeated for each row. Also it makes the menu lazy-loaded and probably more reusable.
yes, but it would bring break changes under the current design since there is no ng-template
inside the nz-dropdown-menu
now.
I had the same problem,When I used nz-dropdown in ngfor, the screen rendering was 3 seconds slower; [Violation] 'load' handler took 2672ms What's a good way to deal with it ?
I think this can be supported in a non-breaking way with the proposal above. Angular Material has a mat-menu which supports both the current API of ng-zorro as well as the proposed one, so it is possible ;-)
https://material.angular.io/components/menu/overview
I would also very much like to see this fixed, having a separate menu for each item in a list creates significant DOM overhead.
I have the same problem. I would also like to have any fix or solution :)
I'm done this by dynamic component workaround
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ContextMenuComponent)
const viewContainerRef = this.contextMenuHost
viewContainerRef.clear()
const componentRef = viewContainerRef.createComponent<ContextMenuComponent>(componentFactory)
componentRef.instance.account = account
componentRef.instance.ready$.subscribe(() => {
this.nzContextMenuService.create($event, componentRef.instance.menu)
})
ContextMenuComponent:
<nz-dropdown-menu #menu='nzDropdownMenu'>
<ul nz-menu>
<li nz-menu-item>{{account.uid}}</li>
<li nz-menu-item>Copy UID</li>
<li nz-menu-item>Copy Cookie</li>
<li nz-menu-item>Copy Login</li>
<li nz-menu-divider></li>
<li nz-menu-item>Update account</li>
</ul>
</nz-dropdown-menu>
Thanks @andepzai , I went with your solution and tweaked it a bit for my own use case.
Until we have a real solution to this, it's a good way to have lazy loaded menus that can easily be migrated from the current menu system.
https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/commit/8ee18609f6914ba7c9204113cb4a03b5d4509354
Need for different trigger data and lazy loading, when dropdown menu is used for each td in a table the performance drops down rapidly as of current and the content can not be easily tuned