【问题标题】:Using dynamic p:menu s inside ui:repeat is not working在 ui:repeat 中使用动态 p:menu 不起作用
【发布时间】:2014-04-26 19:06:42
【问题描述】:

这是场景(简化): 我正在尝试在 ui:repeat 中使用动态 p:menus,如下所示...

<h:form>
   <ui:repeat value="#{bloggerBean.listOfModel}" var="categoryModel" varStatus="loop">
       <p:commandButton id="dynaButton" type="button" 
             value="#{categoryModel.category.name}"/> 
       <p:menu model="#{categoryModel}" overlay="true" trigger="dynaButton" 
                    my="left top" at="left bottom" />
   </ui:repeat>
</h:form>

这样,按钮和菜单项可以正确显示,但只有循环中的最后一个 p:menu 操作侦听器正常工作(在托管 bean 处调用)。显然是因为我没有使用 varStatus 作为模型。 如果我将上面的内容更改为使用 varStatus,如下所示,

<h:form>
   <ui:repeat value="#{bloggerBean.listOfModel}" var="categoryModel" varStatus="loop">
       <p:commandButton id="dynaButton" type="button" 
             value="#{categoryModel.category.name}"/> 
       <p:menu model="#{bloggerBean.listOfModel[loop.index]}" overlay="true" trigger="dynaButton" 
                    my="left top" at="left bottom" />
   </ui:repeat>
</h:form>

显示按钮和菜单,但是每个 p:menu 中的 menuItems 都是空的。

这类似于 BalusC [此处] (Using <ui:repeat><h:inputText> on a List<String> doesn't update model values) 报告的情况!

知道为什么吗? 谢谢!

【问题讨论】:

  • 这是我想要制作的动态面包屑,它允许在任何按钮(带箭头的按钮)上进行动态 p:menu 选择,以便面包屑动态增长或收缩:

标签: jsf primefaces


【解决方案1】:

ui:repeat 无法将选择事件附加到 p:menu 菜单项,但面包屑模型中的最后一个 p:menu 除外。我想出一个解决这个问题的方法,使用 primefaces remoteCommand。这是我更改的内容...我为模型中的每个 menuItems 设置 ActionListener(同时生成动态面包屑),如下所示:

public class CategoryMenuModel implements MenuModel, ActionListener, Serializable {
...
for(Category childCategory : category.getChildCategories()) {
   MenuItem subCategoryItem = new MenuItem();
   ...
   subCategoryItem.addActionListener(this);

}  
...
}

正如我在问题中讨论的那样,这不起作用,因此我将代码更改如下

public class CategoryMenuModel implements MenuModel, ActionListener, Serializable {
...
for(Category childCategory : category.getChildCategories()) {
   MenuItem subCategoryItem = new MenuItem();
   ...

   //Since ui:repeat isn't attaching events to submenus except the last p:menu
   //use instead javascript, pass whatever info as a name value pair
   String parentMapping = "{name: 'parentName', value: '" + category.getName() + "'}";
   String subCategoryMapping = "{name: 'submenuName', value: '" + childCategory.getName() + "'}";
   String remoteMethod = "handleSubmenuSelection([" + parentMapping + "," + subCategoryMapping + "])";
   subCategoryItem.setOnclick(remoteMethod);

}  
...
}

在我的 .xhtml 中,我在所有面包屑子菜单中添加了 p:remoteCommand 监听 menuItems 点击事件

<p:remoteCommand name="handleSubmenuSelection" action="#{bloggerBean.processSubmenuSelection()}" />

最后,我在托管 bean 中添加了一些代码来解析“parentName”和“submenuName”,并处理从模型中的哪个面包屑中选择哪个 menuItem,如下所示:

@ManagedBean
@ViewScoped
public class BloggerBean {
...
public void processSubmenuSelection() {
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> map = context.getExternalContext().getRequestParameterMap();
    this.parentName = map.get("parentName");
    this.submenuName = map.get("submenuName");
    for (CategoryMenuModel model : listOfModel) {
        if(parentName.equals(model.category.getName())){
            model.processSubmenuSelection(submenuName);
            break;
        }
    }
}
...
}

在我的模型中

public class CategoryMenuModel implements MenuModel, ActionListener, Serializable {
...
void processSubmenuSelection(String submenuName) {
    System.out.println("In processSubmenuSelection ... starting");
    for (Category childCategory : category.getChildCategories()) {
        if(childCategory.getName().equals(submenuName)){
            setCategory(childCategory);
            break;
        }
    }
}
...
}

希望,这会帮助有类似问题的人。

【讨论】:

    猜你喜欢
    • 2012-01-13
    • 2013-07-02
    • 1970-01-01
    • 2012-09-29
    • 2014-09-04
    • 2014-05-30
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    相关资源
    最近更新 更多