PrimeFaces CommandButton Action未在Composite内部调用

时间:2011-10-21 18:20:28

标签: jsf-2 primefaces composite-component

在下面的代码中,jsf html commandButton动作被完美地调用。 但是没有调用primefaces commandButton动作。

<ui:component          
              xmlns="http://www.w3.org/1999/xhtml" 
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
           xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
        <composite:attribute 
            name="managedBean"          
            type="java.lang.Object"
            required="true">                    
        </composite:attribute>
    </composite:interface>

    <composite:implementation>
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{cc.attrs.managedBean['value']}"       
                            rendered = "#{!cc.attrs.managedBean['editing']}"/> 
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{cc.attrs.managedBean.value}" 
                             rendered = "#{cc.attrs.managedBean.editing}"/>
                    </h:panelGroup>
                    <!-- ACTION IS CALLED -->                                 
                    <h:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                                    <!-- ACTION IS NOT CALLED -->           
                    <p:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </composite:implementation>
</ui:component>

如果将相同的代码放在复合(普通的xhtml页面)之外,则两者都可以正常工作:

<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html 
    xml:lang="pt" 
        lang="pt"
       xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:f="http://java.sun.com/jsf/core"
     xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
     xmlns:p="http://primefaces.prime.com.tr/ui">

    <h:head id="head">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Item de Texto</title>
    </h:head>
    <h:body id="body">          
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{editableHTMLText.value}" 
                            rendered = "#{!editableHTMLText.editing}"/>
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{editableHTMLText.value}" 
                             rendered = "#{editableHTMLText.editing}"/>
                    </h:panelGroup>

                                    <!-- ACTION IS CALLED -->                         
                    <h:commandButton 
                                action = "#{editableHTMLText.toogleEditing}" 
                                 value = "#{editableHTMLText.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                                    <!-- ACTION IS CALLED -->
                    <p:commandButton 
                                action = "#{editableHTMLText.toogleEditing}" 
                                 value = "#{editableHTMLText.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </h:body>
</html>

这是bean代码:

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;


@ManagedBean
@SessionScoped
public class EditableHTMLText implements Serializable{

    /**
     * 
     */
    private static final long   serialVersionUID    = 8439126615761864409L;

    private String              value               = "Test<br>of<br>HTML<br>text<br><b>ITEM</b><br>";
    private boolean             editing             = false;


    public void toogleEditing(){

        this.setEditing(!this.isEditing());
        System.out.println("Editing State: " + this.editing);
    }


    public String getValue(){

        return value;
    }


    public void setValue(String value){

        this.value = value;
    }


    public boolean isEditing(){

        return editing;
    }


    public void setEditing(boolean editing){

        this.editing = editing;
    }

}

有什么建议吗?

8 个答案:

答案 0 :(得分:18)

今天我用PrimeFaces 5.1遇到了同样的问题。在我的情况下,我没有嵌套表单,我已经使用我想要处理的表单元素在process上设置p:commandButton属性。然而,这还没有奏效。

&#34;解决方案&#34;是将@this添加到要处理的组件列表中,如下所示:

<p:commandButton process="myFormField1 myFormField2 @this">

没有@this(通常不需要,因为按钮本身不应该被处理/验证)我发现无法使任何这些在复合内部工作:

  • <p:commandButton action="#{bean.myAction}"...>
  • <p:commandButton type="button">嵌套<p:ajax event="click" action="#{bean.myAction}"...>
  • <p:commandButton type="button" onclick="myAction()">与关联的<p:remoteCommand name="myAction" action="#{bean.myAction}">

通过调试应用程序,我看到验证和更新模型阶段已正确执行,但随后在调用应用程序阶段没有排队事件,因此未执行任何操作。实际上,我可以在action的{​​{1}}和actionListener属性值中指定我喜欢的任何内容,而不会有任何PrimeFaces或JSF抱怨。

相反,这些可以按预期工作,但是您没有进行部分处理,因此它们可能不是一个可行的解决方案:

  • <p:commandButton>
  • <p:commandButton action="#{bean.myAction}" ajax="false"...>嵌套<p:commandButton type="button"...>

它一定是PrimeFaces的错误。

答案 1 :(得分:5)

当您使用复合组件时,它是否已放置在h:form标签中?嵌套表单时,不会触发命令按钮操作。

另一个问题可能是您正在尝试的ajax部件。 Primefaces按钮具有update属性,但标准JSF没有。它将始终完成页面的完整刷新(嵌入时除外或在其中使用f:ajax标记)

答案 2 :(得分:1)

我还遇到了非触发commandButtons的问题。在我的情况下,ajax和非ajax reqeuests不起作用。 1.如上所述 - 务必删除表格中的所有表格。使用复合材料轻松完成。 2.如果您有多个按钮,请尝试使用标记“process”。 帮助我。

<p:commandButton id="submitButton" value="Submit" type="submit" 
    actionListener="#{bean.save}"
    update="message"
    process="txtComment, @this"
    icon="ui-icon-disk"/>

process="txtComment, @this"执行id为txtComment的inputText的setter方法和commandButton方法。

答案 3 :(得分:0)

您可以尝试在p:commandButton中插入ajax =“false”属性。

答案 4 :(得分:0)

我也遇到了这个问题并测试了你的代码,似乎primefaces无法在同一个“xhtml”中警告你验证错误,但在其他panelGrid中,你可能需要一个父panelGrid来正确封装你所有表单的网格。

如果你完全填满你的整个表格,你会看到你的primefaces commandButton动作被调用,否则它会默默地“消化”你可能有的验证错误。

答案 5 :(得分:0)

为了完整性,请添加上述答案。

上述答案中未涉及的问题之一是Targets

中缺少composite:interface属性

来自JSF的文档

  

targets属性:如果此元素具有方法签名   属性,targets属性的值必须解释为a   空格(不是制表符)分隔的客户端ID列表(相对于顶部   级别组件)   &lt;复合:执行&GT;部分。空间被用作   与IDREFS和NMTOKENS数据类型兼容的分隔符   来自XML Schema。列表中的每个条目都必须解释为   来自的MethodExpression的内部组件的id   必须应用使用页面中的复合组件标记。如果这   element有一个方法签名属性,但是没有targets属性,   name属性的值用作中的单个条目   名单。如果name属性的值不是特殊值之一   name属性的描述中列出的值,目标(或   它的派生值)不需要对应于内在的id   成分

<cc:interface>
    <cc:attribute name="value" />
    <cc:attribute name="action" targets="buttonId" />
    <cc:attribute name="actionListener" targets="buttonId" />
</cc:interface>
<cc:implementation>
    <p:commandButton id="buttonId" value="#{cc.attrs.value}" />
</cc:implementation>

@source:https://stackoverflow.com/a/19680483/1850844

答案 6 :(得分:0)

页面中可能有一些元素,com REQUIRED =“ TRUE”冲突

答案 7 :(得分:-1)

我找到了解决此问题的方法

<composite:implementation>
 <p:commandButton onclick="JS_call_to<p:remoteCommand>" />
</composite:implementation>

在您的主页内定义为
    <p:remoteCommand action="managedBean.call_function()" update="..." />

我已经使用此功能从Composite-Component到我的主页

进行了Gmap调用