Это ошибка Primefaces или Mojarra / MyFaces - PullRequest
0 голосов
/ 28 декабря 2011

Кажется, я не могу вызвать событие, когда нахожусь в пределах column от dataTable. Вот моя простая демонстрация

<h:form id="form">
    <!--This section of p:tree here seems to be the reason causing the event not fired when click the command button-->
    <p:tree value="#{viewBean.root}" var="node" dynamic="true" cache="false"  
                selectionMode="checkbox"  selection="#{treeBean.selectedNode}">  

        <p:ajax event="expand" update=":form:messages" listener="#{viewBean.onNodeExpand}" />  
        <p:ajax event="collapse" update=":form:messages" listener="#{viewBean.onNodeCollapse}" />  
        <p:ajax event="select" update=":form:messages" listener="#{viewBean.onNodeSelect}" />  
        <p:ajax event="unselect" update=":form:messages" listener="#{viewBean.onNodeUnselect}" />  

        <p:treeNode>  
            <h:outputText value="#{node}" />  
        </p:treeNode>  
    </p:tree>
    <h:panelGroup id="mygroup">
            <p:dataTable id="mytable" value="#{viewBean.foodList}" var="item">
                <p:column>
                    #{item}
                </p:column>
                <p:column>
                    <p:commandButton value="delete" 
                                     action="#{viewBean.delete}"
                                     update=":form:mygroup">
                        <f:setPropertyActionListener target="#{viewBean.selectedFood}"
                                                     value="#{item}"/>
                    </p:commandButton>
                </p:column>
            </p:dataTable>
    </h:panelGroup>
</h:form>

а вот мой управляемый боб

@ManagedBean
@ViewScoped
public class ViewBean {

    private TreeNode root;  

    private TreeNode selectedNode;  
    private List<String> foodList;

    private String selectedFood;

    @PostConstruct
    public void init(){

        foodList = new ArrayList<String>();
        foodList.add("Pizza");
        foodList.add("Pasta");
        foodList.add("Hamburger");

        root = new DefaultTreeNode("Root", null);  
        TreeNode node0 = new DefaultTreeNode("Node 0", root);  
        TreeNode node1 = new DefaultTreeNode("Node 1", root);  
        TreeNode node2 = new DefaultTreeNode("Node 2", root);  

        TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);  
        TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);  

        TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);  
        TreeNode node11 = new DefaultTreeNode("Node 1.1", node1);  

        TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);  
        TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);  
        TreeNode node010 = new DefaultTreeNode("Node 0.1.0", node01);  

        TreeNode node100 = new DefaultTreeNode("Node 1.0.0", node10);  
    }

    public void delete(){

        foodList.remove(selectedFood);

    }
    //setter and getter

    public void onNodeExpand(NodeExpandEvent event) {  
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Expanded", event.getTreeNode().toString());  

       FacesContext.getCurrentInstance().addMessage(null, message);  
    }  

    public void onNodeCollapse(NodeCollapseEvent event) {  
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Collapsed", event.getTreeNode().toString());  

       FacesContext.getCurrentInstance().addMessage(null, message);  
    }  

    public void onNodeSelect(NodeSelectEvent event) {  
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", event.getTreeNode().toString());  

       FacesContext.getCurrentInstance().addMessage(null, message);  
    }  

    public void onNodeUnselect(NodeUnselectEvent event) {  
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Unselected", event.getTreeNode().toString());  

        FacesContext.getCurrentInstance().addMessage(null, message);  
    }  
}

Кажется, моя проблема в том, что событие не запускается, а это означает, что delete никогда не вызывается.

Я осмотрелся и знаю, что у Mojarra масса проблем с вложенными компонентами UIData, поэтому я попробовал Mojarra 2.1.4, но проблема так и не решилась. Я пробовал Myfaces 2.1.5, до сих пор не работает !!! Это ошибки Primefaces? Я даже использую h:panelGroup в качестве оболочки для update, но она все равно не работает.

РЕДАКТИРОВАТЬ : Оказывается, p:tree над dataTable является основной причиной события, которое не сработало при нажатии commandButton. Если я удаляю p:tree, то он работает немедленно. Обратите внимание, что сам p:tree прекрасно работает, когда я нажимаю на извлечение, событие запускается на моем управляемом бине.

1 Ответ

5 голосов
/ 29 декабря 2011

Это ошибка в вашем собственном коде.

<partial-response>
  <error>
    <error-name>class javax.el.ELException</error-name>
    <error-message><![CDATA[/index.xhtml @15,84 selection="#{viewBean.selectedNode}": Cannot convert [Lorg.primefaces.model.TreeNode;@fd9b4d of type class [Lorg.primefaces.model.TreeNode; to interface org.primefaces.model.TreeNode]]></error-message>
  </error>
</partial-response>

Конкретное сообщение об исключении предполагает, что <p:tree selection> должен ссылаться на свойство типа TreeNode[], а не TreeNode (обратите внимание на [ префикс идентификатора класса в сообщении, который указывает тип массива).Итак, исправьте это соответствующим образом:

<p:tree selection="#{treeBean.selectedNodes}">

с

private TreeNode[] selectedNodes;

Независимо от того, у вас есть и <p:tree>, и <p:dataTable> внутри одной и той же формы "бога".Таким образом, любое действие в одном из них будет передавать все и на другой компонент.Если дерево и таблица никоим образом не связаны друг с другом, то каждый из них должен быть помещен в свой собственный <h:form>.Или необходимо добавить атрибут process к командным ссылкам / кнопкам для обработки только интересующего содержащего компонента, например process="mytable" для кнопки внутри таблицы.

...