【问题标题】:Primefaces Dynamic Mega Menu - Cannot remove the same component twicePrimefaces 动态超级菜单 - 不能两次删除相同的组件
【发布时间】:2013-02-13 17:23:14
【问题描述】:

我用带有模型的巨型菜单更改了我的静态菜单文件 (header.xhtml)。 像这样:

          <p:megaMenu model="#{menuController.megaModel}" autoDisplay="false" styleClass="menu-bar"  >

          </p:megaMenu>

到目前为止一切都很好,它工作得很好并且按照我的预期构建。 问题是,在我的表单页面上,当第二次验证失败时...... 我收到此错误:

 javax.faces.FacesException: Cannot remove the same component twice: j_idt15:j_id2     com.sun.faces.context.StateContext$AddRemoveListener.handleAddRemoveWithAutoPrune(StateContext.java:493)
        com.sun.faces.context.StateContext$AddRemoveListener.handleRemove(StateContext.java:372)

查看生成的 HTML 我找不到这个字符串“j_idt15:j_id2”,但我可以找到:

   <div id="j_idt14:j_idt15" class="ui-menu ui-menubar ui-megamenu ui-widget ui-widget-content ui-corner-all ui-helper-clearfix menu-bar" role="menubar">

还有这个:

所以...我真的不明白。我的 MenuController 是一个 sessionBean:

@Component
@Scope("session")
public class MenuController implements Serializable {

@PostConstruct
   public void init(){
   todosModulos = moduloService.findAll();
   modulosAcesso = extrairModulos();
   createMegaMenu();
}

...所以.. 一些注意事项:

我发现这个错误发生在 2.1.9 以上的 Mojarra 版本上。 (我使用的是 2.1.10)。因此,一种可能的解决方案是将 JSF imp 更改为 My Faces。 我试过了,但它破坏了我的结构(我的复合组件停止工作并且 dynaForm 也停止了)。

我尝试了一些解决方法,但没有成功。这是我尝试过的: Overriding AbstractMenuMarlon Patrick's solution (PT-BR)

根本不起作用=[

编辑 -> 创建菜单项

 MenuItem anItem = new MenuItem();
 anItem.setOutcome(item.getOutcome());
 anItem.setValue(item.getRotulo());
 anItem.setIcon(item.getIcone());       

【问题讨论】:

  • 你有没有试过打电话给anItem.setTransient(true)?这对我有用。

标签: jsf primefaces


【解决方案1】:

据我所见,您已经尝试了我的两种解决方法:覆盖 AbstractMenu 并放置 PhaseListener。

好吧,我意识到我遇到的问题是 MenuBar 和您尝试使用的组件是 MegaMenu,也许是我不适用于 MegaMenu 的解决方案,尽管我相信应该可以。

我要对你说的是检查以下内容:

1 - 当您覆盖类 AbstractMenu 时,您确定 PrimeFaces 开始使用它吗?以确保它在那里放置一个断点以及他是否看到执行流程。如果你不停止,因为 PrimeFaces 仍在使用它自己的类。

2 - 在尝试将解决方案与 PhaseListener 一起使用时,我现在更喜欢并使用它,您注意到您需要用自己的代码替换一段代码?基本上,您只需要删除作为链接的菜单项的操作,因为它们会导致此问题。菜单项是应该保留的操作。就我而言,我知道 ID 是什么动作或链接,那么您将不得不以某种方式通过 ID 来区分。另外,设置一个断点以确保您的 PhaseListener 已正确注册并且正在拦截执行流程。

【讨论】:

  • 好的,让我们关注 PhaseListener 解决方案好吗?我没注意到。问题是我所有的 MenuItems 都使用 setOutcome 方法。我将编辑帖子以向您展示代码
  • 这是一个非常明确的答案。如果它满足您的要求,请标记它。
  • 好吧,就我而言,我使用 setUrl (link) setActionExpression,如下所示: 1 - menuItemLink.setUrl ("/changePassword.xhtml"); 2 - menuItemAction.setActionExpression(logoutMethodExpression);正如我所说,唯一的 PhaseListener 必须删除链接,从而删除在呈现页面后它们将不起作用的操作。在您的情况下,我不确定 setOutcome 的行为是什么,但是会给出错误,因为我认为它的工作方式与 setUrl 相同,因此可以使用 setOutcome 删除所有菜单项。应该permancer只有那些使用setActionExpression的人。
猜你喜欢
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多