PrimeFaces CommandButton 操作未在 Composite 内调用
在下面的代码中,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;
}
}
有什么建议吗?
In the code bellow the jsf html commandButton action is called perfectly.
But primefaces commandButton action is not called.
<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>
If place the same code is outside a composite (a normal xhtml page), both work fine:
<!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>
This is the bean code:
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;
}
}
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
今天我在使用 PrimeFaces 5.1 时遇到了同样的问题。就我而言,我没有嵌套表单,并且我已经使用我想要处理的表单元素在
p:commandButton
上设置了process
属性。然而这还没有奏效。“解决方案”是将
@this
添加到要处理的组件列表中,如下所示:@this
(通常不需要,因为按钮本身不需要处理/验证)我发现没有办法让这些在组合内部工作:
带有嵌套的
以及关联的通过调试应用程序,我看到验证和更新模型阶段已正确执行,但在调用应用程序阶段不存在排队事件,因此未执行任何操作。实际上,我可以在
的action
和actionListener
属性值中指定任何我喜欢的内容,而不会引起 PrimeFaces 或 JSF 的抱怨以任何方式。相反,这些确实可以正常工作,但是您没有进行部分处理,因此它们可能不是一个可行的解决方案:
嵌套这一定是 PrimeFaces 的错误。
Today I hit this exact same problem with PrimeFaces 5.1. In my case I had no nested forms and I was already setting the
process
attribute on thep:commandButton
with the form elements I wanted to be processed. However this didn't work yet.The "solution" was to add
@this
to the list of components to process, like this:<p:commandButton process="myFormField1 myFormField2 @this">
Without
@this
(which is not usually needed, since the button itself shouldn't need to be processed/validated) I found no way to make any of these to work inside a composite:<p:commandButton action="#{bean.myAction}"...>
<p:commandButton type="button">
with nested<p:ajax event="click" action="#{bean.myAction}"...>
<p:commandButton type="button" onclick="myAction()">
with associated<p:remoteCommand name="myAction" action="#{bean.myAction}">
By debugging the application, I saw that the validation and update model phases were correctly executed, but then in the invoke application phase no queued event was present and hence no action was performed. Actually, I could specify anything I liked inside the
action
andactionListener
attribute values of<p:commandButton>
without having either PrimeFaces or JSF complain in any way.These, instead, do work as they should, but you don't have partial processing in place, so they may not be a viable solution:
<p:commandButton action="#{bean.myAction}" ajax="false"...>
<p:commandButton type="button"...>
with nested<f:ajax event="click" action="#{bean.myAction}"...>
It must be a PrimeFaces bug.
当你使用复合组件时,它是否已经放在ah:form标签中了?当您有嵌套表单时,不会触发命令按钮操作。
另一个问题可能是您正在尝试的 ajax 部分。 Primefaces 按钮具有更新属性,但标准 JSF 按钮没有该属性。它将始终对页面进行完全刷新(除非嵌套在其中或在其中使用 f:ajax 标记)
When you used the composite component, was it already placed in a h:form tag? When you have nested forms, command button action isn't triggered.
Another issue can be the ajax parts that you are trying. Primefaces button has the update attribute, but the standard JSF one does not have that. It will do always a complete refresh of the page (except when nested in or f:ajax tag is used inside it)
您可以尝试在 p:commandButton 中插入 ajax="false" 属性。
You can try to insert ajax="false" attribute in p:commandButton.
我也遇到了非触发命令按钮的问题。就我而言,ajax 和非 ajax 请求不起作用。
1.如上所述-请务必删除表单中的所有表单。复合使用很容易完成。
2. 如果您有多个按钮,请尝试使用“process”标志。
对我的情况有帮助。
process="txtComment, @this"
执行id为txtComment
的inputText的setter方法和commandButton方法。I had also problems with non-triggering commandButtons. In my case ajax and non-ajax reqeuests didn't work.
1. as described above - be sure to delete all form's in form's. easy done with composite usage.
2. if you have several buttons, try to use the flag "process".
Helped in my case.
process="txtComment, @this"
executes the setter method of inputText with idtxtComment
and the commandButton method.可能您的页面中有一些元素,com REQUIRED =“TRUE”是冲突的
probably you have some elements in your page, com REQUIRED="TRUE" is conflicting
我也遇到了这个问题并测试了您的代码,似乎 primefaces 无法在同一个“xhtml”中警告您验证错误,但在其他 panelGrid 中,您可能需要一个父 panelGrid 来正确封装所有表单的网格。
如果您完全填写了整个表单,您将看到您的 primefaces commandButton 操作被调用,否则它会默默地“消化”您可能遇到的验证错误。
I also hit this problem and tested out your codes, it seems that primefaces is unable to warn you validation errors in the same "xhtml" but in other panelGrids, you may need a parent panelGrid to properly encapsulate all your form's grids.
If you fill up your entire form completely, you will see that your primefaces commandButton action is called upon, otherwise it would silently "digest" the validation errors you may have.
为了完整起见,添加到上述答案中。
上述答案中未涵盖的问题之一是
composite:interface
中缺少Targets
属性来自 JSF 的文档
@source:https://stackoverflow.com/a/19680483/1850844
To add to the above answers, for completeness.
One of the issue not covered in the above answers is the missing
Targets
attribute incomposite:interface
From the docs of JSF
@source: https://stackoverflow.com/a/19680483/1850844
我在您的主页中找到了解决此问题的方法
我已经用它从复合组件到我的主页进行了 Gmap 调用
I Found a workaround for this Problem
Inside your mainpage define with
<p:remoteCommand action="managedBean.call_function()" update="..." />
I have made a Gmap Call with this from a Composite-Component to my Mainpage