primeng icon indicating copy to clipboard operation
primeng copied to clipboard

Not able to return MenuItem[] through a function to model attribute in SplitButton component.

Open joseespinozac opened this issue 1 month ago • 4 comments

Describe the bug

Hello everyone,

I was trying to pass a function to the [model] attribute in split-button component, but for some reason even when I'm returning a valid MenuItem[] array. the options in the dropdown freezes completely and became unclickable. I added a stackblitz reproducing the issue.

Pull Request Link

No response

Reason for not contributing a PR

  • [x] Lack of time
  • [x] Unsure how to implement the fix/feature
  • [x] Difficulty understanding the codebase
  • [x] Other

Other Reason

No response

Reproducer

https://stackblitz.com/edit/efczrox7?file=src%2Fapp%2Fsplit-button-basic-demo.ts

Environment

I-m working with angular v20

Angular version

20.0.0

PrimeNG version

v20

Node version

20.19.4

Browser(s)

Chrome Versión 142.0.7444.176

Steps to reproduce the behavior

  1. Add splitbutton to template 2. create function that returns your MenuItem[](your menu) 3. Pass that function to model attribute 4. Buttons in dropdown will not work

Expected behavior

The button should be clickable, and the model should be able to receive a MenuItem array through a function return

joseespinozac avatar Nov 23 '25 08:11 joseespinozac

Image

SplitButton uses TieredMenu under the hood. For MenuItems containing routerLink-property will create an Angular RouterLink. But since the Stackblitz Example has no Angular Router Setup, it will throw a Dependency Injection Error (multiple times because of ChangeDetection + Non-Signal Function call):

Image

raven-dever avatar Nov 24 '25 19:11 raven-dever

Image SplitButton uses TieredMenu under the hood. For MenuItems containing `routerLink`-property will create an Angular RouterLink. But since the Stackblitz Example has no Angular Router Setup, it will throw a Dependency Injection Error (multiple times because of ChangeDetection + Non-Signal Function call): Image

HI,

Thanks for the feedback, I removed the items that used routerlink since they are not necessary to reproduce the error. I made it simplier and just using labels and commands. The bug is still ocurring. Stackblitz updated

Image

joseespinozac avatar Nov 24 '25 21:11 joseespinozac

That's actually a seperate issue due to ChangeDetection and Re-Rendering: Zone.js triggers ChangeDetection on almost any Events or Event-Listeners regarding HTML-Elements. TieredMenuSub has internal actions on hover: https://github.com/primefaces/primeng/blob/c903ce36b661327ce076fbbe2442c8ad6197e47f/packages/primeng/src/tieredmenu/tieredmenu.ts#L363 Which in turn propagates ChangeDetection and Re-Render. getMenuItems is executed -> New Array-Instance passed to SplitButton options -> TieredMenu creates new TieredMenuSub Instances -> Hovering over an item triggers new ChangeDetection cycle

Here a demonstration: Calling a regular function causes infinite CD, because the the bound reference isn't stable. But computed signals retain values when no reactive dependencies are changing: https://stackblitz.com/edit/efczrox7-vdiev4kt?file=src%2Fapp%2Fsplit-button-basic-demo.ts

raven-dever avatar Nov 24 '25 23:11 raven-dever

Passing a function returning items is not a good idea because of change detection concerns.

Declaring a dedicated property and passing this one solves the issue:

public menuItems = signal<MenuItem[]>(this.getMenuItems());
<p-splitbutton label="Save" (onClick)="save()" [model]="menuItems()" />

danielxbauer avatar Nov 30 '25 14:11 danielxbauer