ng-zorro-antd icon indicating copy to clipboard operation
ng-zorro-antd copied to clipboard

Allow for ng-template as input for dropdown component

Open Supamiu opened this issue 4 years ago • 9 comments

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.

Supamiu avatar Jan 20 '20 12:01 Supamiu

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-menunow ref https://github.com/angular/angular/issues/14842

vthinkxie avatar Jan 29 '20 08:01 vthinkxie

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.

Supamiu avatar Feb 04 '20 10:02 Supamiu

yes, but it would bring break changes under the current design since there is no ng-template inside the nz-dropdown-menu now.

vthinkxie avatar Feb 04 '20 11:02 vthinkxie

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 ?

qwz873112851 avatar Oct 08 '20 12:10 qwz873112851

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.

Airblader avatar Oct 10 '20 06:10 Airblader

I have the same problem. I would also like to have any fix or solution :)

CRozan59 avatar Feb 02 '21 13:02 CRozan59

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>

ducan-ne avatar Aug 18 '21 01:08 ducan-ne

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

Supamiu avatar Aug 26 '21 10:08 Supamiu

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

NathanIceSea avatar Aug 26 '22 03:08 NathanIceSea