JSF MethodExpression 没有触发我的支持 bean 操作
我的问题是我的代码没有触发我的支持 bean 中的操作。 代码如下:
HtmlCommandButton replyCommentButton = new HtmlCommandButton();
replyCommentButton.setId("replyCommentButton" + commentCounter);
replyCommentButton.setValue("Create reply");
String action = "#{Handler.action_replyToComment}";
MethodExpression methodExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
new Class<?>[0]);
replyCommentButton.setActionExpression(methodExpression);
在我的名为 RequestHandlerBean 的支持 bean(在 FacesConfig 中定义为 Handler)中,我有以下代码:
public void action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
}
有人发现为什么当我单击按钮时没有任何反应吗? 它没有正确触发事件。 html 代码的来源如下:
<input id="replyCommentButton1" type="submit" value="Create reply"
name="replyCommentButton1"/>
我们可以看到 HTML 中没有定义任何操作。
编辑2:我刚刚在Javadoc中发现我的操作方法必须是公共字符串。 我现在已经在我的支持 bean 中更改了这一点,因此我的支持 bean 中的代码是:
public String action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
return null;
}
Edit2:我还确保将其封装在标签中,但仍然没有运气。 元素上不应该有一个 action 属性吗?
Edit3:我的 bean 在我的 faces-config 中定义如下:
<managed-bean>
<description>
Handles the specific request.
</description>
<managed-bean-name>Handler</managed-bean-name>
<managed-bean-class>no.ngt.tech.rt2.beans.RequestHandlerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
另外,如果我选择在 JSF 页面中输出,如下所示:
<a4j:commandButton action="#{Handler.action_replyToComment}" value="Reply" />
效果很好
EDIT 4 - MY JSP PAGE 注意我现在也尝试使用已弃用的 setAction(methodBinding) ,但遗憾的是它也不起作用。
<%@ include file="_includes.jsp" %>
<f:view>
<html>
<head>
<title><h:outputText value="#{msgs.title}" /></title>
</head>
<body>
<br /><br /><br />
<%@ include file="_menu.jsp" %>
<rich:tabPanel switchType="client">
<rich:tab id="commentsTab" label="Comments" rendered="#{Handler.editRequest}">
<h:form>
<ngt:commentTree binding="#{Handler.commentTree}" value="#{Handler.comments}" />
<br />
<a4j:commandButton action="#{Handler.action_replyToComment}" value="testbutton" />
</h:form>
</rich:tab>
</rich:tabPanel>
</body>
</html>
</f:view>
menu.jsp:
<h:form>
<rich:toolBar itemSeparator="line" styleClass="toolbar" contentClass="toolbar" height="22">
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="Front" action="#{newRT.action_showFront}" />
</rich:toolBarGroup>
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="New request" action="#{Step.action_showSteps}" />
</rich:toolBarGroup>
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="Requests" action="#{Handler.action_showRequestsView}" />
</rich:toolBarGroup>
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="Control-panel" action="#" />
</rich:toolBarGroup>
<rich:toolBarGroup location="right">
<h:inputText styleClass="barsearch" value="#{Handler.search}" />
<a4j:commandButton styleClass="barsearchbutton" action="#{Handler.action_GetRequestFromID}" value="Search" />
</rich:toolBarGroup>
</rich:toolBar>
</h:form>
<br/><br/>
Includes.jsp
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="a4j" uri="http://richfaces.org/a4j" %>
<%@ taglib prefix="rich" uri="http://richfaces.org/rich"%>
<%@ taglib prefix="ngt" uri="http://MySpecialTagLib.no/"%>
编辑 7 - UIComponent 的 Java 代码:
这是 CommentsTreeUI.java:
public class CommentsTreeUI extends UIOutput {
private static Logger logger = Logger.getLogger(CommentsTreeUI.class.getName());
@Override
public void encodeBegin(FacesContext context) throws IOException {
List<CommentTag> value = (List<CommentTag>) getAttributes().get("value");
int commentCounter = 0;
if (value != null) {
for (CommentTag comment : value) {
commentCounter++;
ResponseWriter commentContainerWriter = context.getResponseWriter();
commentContainerWriter.startElement("div", this);
commentContainerWriter.writeAttribute("id", "Comment" + commentCounter, null);
String width = comment.getWidth();
String height = comment.getHeight();
String style = comment.getStyle();
style = (style != null) ? style + ";" : "";
if (width != null) {
style += "width:" + width + ";";
}
if (height != null) {
style += "height:" + height + ";";
}
commentContainerWriter.writeAttribute("style", style, null);
String newComment = comment.getNewComment();
if (newComment == null) {
newComment = "false";
}
String level = comment.getLevel();
if (level != null) {
level = "commentContainerLevel" + level + newComment;
}
commentContainerWriter.writeAttribute("class", level, null);
String title = comment.getTitle();
if (title != null) {
commentContainerWriter.writeAttribute("title", title, null);
}
String titleText = comment.getTitleText();
if (titleText != null) {
ResponseWriter titleTextWriter = context.getResponseWriter();
UIOutput titleTextComponent = new UIOutput();
titleTextWriter.startElement("div", titleTextComponent);
titleTextWriter.writeAttribute("class", "commentHeaderText" + newComment, null);
titleTextWriter.writeText(titleText + " | ", null);
titleTextWriter.startElement("a", titleTextComponent);
titleTextWriter.writeAttribute("onclick", "showCommentReply('CommentReply" + commentCounter + "')", null);
titleTextWriter.writeAttribute("class", "reply", null);
titleTextWriter.writeText("Reply", null);
titleTextWriter.endElement("a");
titleTextWriter.endElement("div");
}
String commentBody = comment.getCommentBody();
if (commentBody != null) {
ResponseWriter commentBodyWriter = context.getResponseWriter();
UIOutput commentBodyComponent = new UIOutput();
commentBodyWriter.startElement("div", commentBodyComponent);
commentBodyWriter.writeText(commentBody, null);
commentBodyWriter.endElement("div");
}
ResponseWriter replyContainerWriter = context.getResponseWriter();
UIOutput replyContainerComponent = new UIOutput();
replyContainerWriter.startElement("div", replyContainerComponent);
commentContainerWriter.writeAttribute("id", "CommentReply" + commentCounter, null);
replyContainerWriter.writeAttribute("class", "replyContainer", null);
ResponseWriter replyHeaderWriter = context.getResponseWriter();
UIOutput replyHeaderComponent = new UIOutput();
replyHeaderWriter.startElement("div", replyHeaderComponent);
replyHeaderWriter.writeAttribute("class", "replyHeaderContainer", null);
replyHeaderWriter.endElement("div");
ResponseWriter replyFormWriter = context.getResponseWriter();
UIInput replyFormComponent = new UIInput();
replyFormWriter.startElement("fieldset", replyFormComponent);
replyFormWriter.startElement("textarea", replyFormComponent);
replyFormWriter.writeAttribute("type", "textarea", null);
replyFormWriter.writeAttribute("rows", "5", null);
replyFormWriter.writeAttribute("cols", "76", null);
replyFormWriter.writeText("Write your answer here", null);
replyFormWriter.endElement("textarea");
//TODO: Fix so button has action to backing bean
HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton();
replyCommentButton.setId("replyCommentButton" + commentCounter);
replyCommentButton.setValue("Create reply");
String action = "#{RequestHandlerBean.action_replyToComment}";
//replyCommentButton.setReRender("commentsTree");
ExpressionFactory factory = context.getApplication().getExpressionFactory();
Class [] argtypes=new Class[1];
argtypes[0]=ActionEvent.class;
MethodExpression replyActionExpression = factory.createMethodExpression(context.getELContext(), action, null, argtypes);
replyCommentButton.setActionExpression(replyActionExpression);
MethodExpression methodExpression = context.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(context.getCurrentInstance().getELContext(), action, null, new Class<?>[0]);
replyCommentButton.setActionExpression(methodExpression);
/*
replyCommentButton.setAction(context.getApplication().createMethodBinding(action, argtypes));
*/
replyCommentButton.encodeAll(context);
//Todo above
replyFormWriter.writeText(" ", null);
replyFormWriter.startElement("input", replyFormComponent);
replyFormWriter.writeAttribute("type", "button", null);
replyFormWriter.writeAttribute("value", "Cancel ", null);
replyFormWriter.writeAttribute("onclick", "hideCommentReply('CommentReply" + commentCounter + "')", title);
replyFormWriter.endElement("input");
replyFormWriter.endElement("fieldset");
replyContainerWriter.endElement("div");
commentContainerWriter.endElement("div");
}
} else { //value==null
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeAttribute("id", getClientId(context), null);
String width = (String) getAttributes().get("width");
String height = (String) getAttributes().get("height");
String style = (String) getAttributes().get("style");
style = (style != null) ? style + ";" : "";
if (width != null) {
style += "width:" + width + ";";
}
if (height != null) {
style += "height:" + height + ";";
}
writer.writeAttribute("style", style, null);
String styleClass = (String) getAttributes().get("styleClass");
if (styleClass != null) {
writer.writeAttribute("class", styleClass, null);
}
String title = (String) getAttributes().get("title");
if (title != null) {
writer.writeAttribute("title", title, null);
}
}
}
@Override
public void encodeEnd(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement("div");
}
这是 CommentsTreeTag:
public class CommentsTreeTag extends UIComponentTag {
String style;
String styleClass;
String title;
String width;
String height;
String value;
Long parentId;
public void release() {
// the super class method should be called
super.release();
style = null;
styleClass = null;
title = null;
height = null;
width = null;
parentId = null;
value = null;
}
@Override
protected void setProperties(UIComponent component) {
// the super class method should be called
super.setProperties(component);
if (style != null) {
component.getAttributes().put("style", style);
}
if (styleClass != null) {
component.getAttributes().put("styleClass", styleClass);
}
if (width != null) {
component.getAttributes().put("width", width);
}
if (height != null) {
component.getAttributes().put("height", height);
}
if (title != null) {
if (isValueReference(title)) {
ValueBinding vb =
getFacesContext().getApplication().createValueBinding(title);
component.setValueBinding("title", vb);
} else {
component.getAttributes().put("title", title);
}
}
if (value != null) {
if (isValueReference(value)) {
ValueBinding vb =
getFacesContext().getApplication().createValueBinding(value);
component.setValueBinding("value", vb);
getFacesContext().getApplication().createValueBinding(value);
} else {
component.getAttributes().put("value", value);
}
}
if (parentId != null) {
component.getAttributes().put("parentId", parentId);
}
}
public String getComponentType() {
return "commentTree";
}
public String getRendererType() {
// null means the component renders itself
return null;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
public String getStyle() {
return style;
}
public void setStyle(String style) {
this.style = style;
}
public String getStyleClass() {
return styleClass;
}
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
I have the problem that my code isn't triggering the action in my backing bean. The code is as follows:
HtmlCommandButton replyCommentButton = new HtmlCommandButton();
replyCommentButton.setId("replyCommentButton" + commentCounter);
replyCommentButton.setValue("Create reply");
String action = "#{Handler.action_replyToComment}";
MethodExpression methodExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
new Class<?>[0]);
replyCommentButton.setActionExpression(methodExpression);
In my backing bean called RequestHandlerBean, defined in FacesConfig as Handler, I have the following code:
public void action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
}
Does anyone spot why nothing happens when I click the button? It isn't triggering the event properly. The source of the html code is as follows:
<input id="replyCommentButton1" type="submit" value="Create reply"
name="replyCommentButton1"/>
As we can see there's no action defined in the HTML.
Edit 2: I just found out in Javadoc that my action method has to be a public String. I've changed this in my backing bean now so the code in my backing bean is:
public String action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
return null;
}
Edit2: I've also made sure that I have it encapsulated within a tag, but still no luck. Shouldn't there be a action attribute on the element?
Edit3: My bean is defined in my faces-config like this:
<managed-bean>
<description>
Handles the specific request.
</description>
<managed-bean-name>Handler</managed-bean-name>
<managed-bean-class>no.ngt.tech.rt2.beans.RequestHandlerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Also if I choose to output in my JSF page like this:
<a4j:commandButton action="#{Handler.action_replyToComment}" value="Reply" />
That works perfectly
EDIT 4 - MY JSP PAGE
Note Ive also tried using the depreciated setAction(methodBinding) now too, but sadly it didnt work either.
<%@ include file="_includes.jsp" %>
<f:view>
<html>
<head>
<title><h:outputText value="#{msgs.title}" /></title>
</head>
<body>
<br /><br /><br />
<%@ include file="_menu.jsp" %>
<rich:tabPanel switchType="client">
<rich:tab id="commentsTab" label="Comments" rendered="#{Handler.editRequest}">
<h:form>
<ngt:commentTree binding="#{Handler.commentTree}" value="#{Handler.comments}" />
<br />
<a4j:commandButton action="#{Handler.action_replyToComment}" value="testbutton" />
</h:form>
</rich:tab>
</rich:tabPanel>
</body>
</html>
</f:view>
menu.jsp:
<h:form>
<rich:toolBar itemSeparator="line" styleClass="toolbar" contentClass="toolbar" height="22">
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="Front" action="#{newRT.action_showFront}" />
</rich:toolBarGroup>
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="New request" action="#{Step.action_showSteps}" />
</rich:toolBarGroup>
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="Requests" action="#{Handler.action_showRequestsView}" />
</rich:toolBarGroup>
<rich:toolBarGroup>
<rich:menuItem submitMode="server" value="Control-panel" action="#" />
</rich:toolBarGroup>
<rich:toolBarGroup location="right">
<h:inputText styleClass="barsearch" value="#{Handler.search}" />
<a4j:commandButton styleClass="barsearchbutton" action="#{Handler.action_GetRequestFromID}" value="Search" />
</rich:toolBarGroup>
</rich:toolBar>
</h:form>
<br/><br/>
Includes.jsp
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="a4j" uri="http://richfaces.org/a4j" %>
<%@ taglib prefix="rich" uri="http://richfaces.org/rich"%>
<%@ taglib prefix="ngt" uri="http://MySpecialTagLib.no/"%>
Edit 7 - Java code for UIComponent:
This is CommentsTreeUI.java:
public class CommentsTreeUI extends UIOutput {
private static Logger logger = Logger.getLogger(CommentsTreeUI.class.getName());
@Override
public void encodeBegin(FacesContext context) throws IOException {
List<CommentTag> value = (List<CommentTag>) getAttributes().get("value");
int commentCounter = 0;
if (value != null) {
for (CommentTag comment : value) {
commentCounter++;
ResponseWriter commentContainerWriter = context.getResponseWriter();
commentContainerWriter.startElement("div", this);
commentContainerWriter.writeAttribute("id", "Comment" + commentCounter, null);
String width = comment.getWidth();
String height = comment.getHeight();
String style = comment.getStyle();
style = (style != null) ? style + ";" : "";
if (width != null) {
style += "width:" + width + ";";
}
if (height != null) {
style += "height:" + height + ";";
}
commentContainerWriter.writeAttribute("style", style, null);
String newComment = comment.getNewComment();
if (newComment == null) {
newComment = "false";
}
String level = comment.getLevel();
if (level != null) {
level = "commentContainerLevel" + level + newComment;
}
commentContainerWriter.writeAttribute("class", level, null);
String title = comment.getTitle();
if (title != null) {
commentContainerWriter.writeAttribute("title", title, null);
}
String titleText = comment.getTitleText();
if (titleText != null) {
ResponseWriter titleTextWriter = context.getResponseWriter();
UIOutput titleTextComponent = new UIOutput();
titleTextWriter.startElement("div", titleTextComponent);
titleTextWriter.writeAttribute("class", "commentHeaderText" + newComment, null);
titleTextWriter.writeText(titleText + " | ", null);
titleTextWriter.startElement("a", titleTextComponent);
titleTextWriter.writeAttribute("onclick", "showCommentReply('CommentReply" + commentCounter + "')", null);
titleTextWriter.writeAttribute("class", "reply", null);
titleTextWriter.writeText("Reply", null);
titleTextWriter.endElement("a");
titleTextWriter.endElement("div");
}
String commentBody = comment.getCommentBody();
if (commentBody != null) {
ResponseWriter commentBodyWriter = context.getResponseWriter();
UIOutput commentBodyComponent = new UIOutput();
commentBodyWriter.startElement("div", commentBodyComponent);
commentBodyWriter.writeText(commentBody, null);
commentBodyWriter.endElement("div");
}
ResponseWriter replyContainerWriter = context.getResponseWriter();
UIOutput replyContainerComponent = new UIOutput();
replyContainerWriter.startElement("div", replyContainerComponent);
commentContainerWriter.writeAttribute("id", "CommentReply" + commentCounter, null);
replyContainerWriter.writeAttribute("class", "replyContainer", null);
ResponseWriter replyHeaderWriter = context.getResponseWriter();
UIOutput replyHeaderComponent = new UIOutput();
replyHeaderWriter.startElement("div", replyHeaderComponent);
replyHeaderWriter.writeAttribute("class", "replyHeaderContainer", null);
replyHeaderWriter.endElement("div");
ResponseWriter replyFormWriter = context.getResponseWriter();
UIInput replyFormComponent = new UIInput();
replyFormWriter.startElement("fieldset", replyFormComponent);
replyFormWriter.startElement("textarea", replyFormComponent);
replyFormWriter.writeAttribute("type", "textarea", null);
replyFormWriter.writeAttribute("rows", "5", null);
replyFormWriter.writeAttribute("cols", "76", null);
replyFormWriter.writeText("Write your answer here", null);
replyFormWriter.endElement("textarea");
//TODO: Fix so button has action to backing bean
HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton();
replyCommentButton.setId("replyCommentButton" + commentCounter);
replyCommentButton.setValue("Create reply");
String action = "#{RequestHandlerBean.action_replyToComment}";
//replyCommentButton.setReRender("commentsTree");
ExpressionFactory factory = context.getApplication().getExpressionFactory();
Class [] argtypes=new Class[1];
argtypes[0]=ActionEvent.class;
MethodExpression replyActionExpression = factory.createMethodExpression(context.getELContext(), action, null, argtypes);
replyCommentButton.setActionExpression(replyActionExpression);
MethodExpression methodExpression = context.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(context.getCurrentInstance().getELContext(), action, null, new Class<?>[0]);
replyCommentButton.setActionExpression(methodExpression);
/*
replyCommentButton.setAction(context.getApplication().createMethodBinding(action, argtypes));
*/
replyCommentButton.encodeAll(context);
//Todo above
replyFormWriter.writeText(" ", null);
replyFormWriter.startElement("input", replyFormComponent);
replyFormWriter.writeAttribute("type", "button", null);
replyFormWriter.writeAttribute("value", "Cancel ", null);
replyFormWriter.writeAttribute("onclick", "hideCommentReply('CommentReply" + commentCounter + "')", title);
replyFormWriter.endElement("input");
replyFormWriter.endElement("fieldset");
replyContainerWriter.endElement("div");
commentContainerWriter.endElement("div");
}
} else { //value==null
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeAttribute("id", getClientId(context), null);
String width = (String) getAttributes().get("width");
String height = (String) getAttributes().get("height");
String style = (String) getAttributes().get("style");
style = (style != null) ? style + ";" : "";
if (width != null) {
style += "width:" + width + ";";
}
if (height != null) {
style += "height:" + height + ";";
}
writer.writeAttribute("style", style, null);
String styleClass = (String) getAttributes().get("styleClass");
if (styleClass != null) {
writer.writeAttribute("class", styleClass, null);
}
String title = (String) getAttributes().get("title");
if (title != null) {
writer.writeAttribute("title", title, null);
}
}
}
@Override
public void encodeEnd(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement("div");
}
This is CommenstTreeTag:
public class CommentsTreeTag extends UIComponentTag {
String style;
String styleClass;
String title;
String width;
String height;
String value;
Long parentId;
public void release() {
// the super class method should be called
super.release();
style = null;
styleClass = null;
title = null;
height = null;
width = null;
parentId = null;
value = null;
}
@Override
protected void setProperties(UIComponent component) {
// the super class method should be called
super.setProperties(component);
if (style != null) {
component.getAttributes().put("style", style);
}
if (styleClass != null) {
component.getAttributes().put("styleClass", styleClass);
}
if (width != null) {
component.getAttributes().put("width", width);
}
if (height != null) {
component.getAttributes().put("height", height);
}
if (title != null) {
if (isValueReference(title)) {
ValueBinding vb =
getFacesContext().getApplication().createValueBinding(title);
component.setValueBinding("title", vb);
} else {
component.getAttributes().put("title", title);
}
}
if (value != null) {
if (isValueReference(value)) {
ValueBinding vb =
getFacesContext().getApplication().createValueBinding(value);
component.setValueBinding("value", vb);
getFacesContext().getApplication().createValueBinding(value);
} else {
component.getAttributes().put("value", value);
}
}
if (parentId != null) {
component.getAttributes().put("parentId", parentId);
}
}
public String getComponentType() {
return "commentTree";
}
public String getRendererType() {
// null means the component renders itself
return null;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
public String getStyle() {
return style;
}
public void setStyle(String style) {
this.style = style;
}
public String getStyleClass() {
return styleClass;
}
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您遇到的问题是由于您在 JSF 组件树中添加 commandButton 的方式造成的,或者更准确地说,是由于您没有将其添加到组件树中的方式造成的。
由于您没有将 commandButton 附加到 JSF 组件树,因此当呈现该组件时(通过调用 .encodeAll() 方法),它不会找到该组件嵌套的表单。
因此,HTML 输入未正确创建。
也许您可以尝试将创建的命令按钮直接添加到表单中,然后再要求渲染它。 您可以使用以下代码来做到这一点:
请注意,我已经测试了此代码,因此也许您需要稍微修改一下...
如果它仍然不起作用,也许您需要检查代码以便在渲染类之外或encodeBegin之外创建commandButton...我认为在渲染阶段修改JSF组件树不是一个好主意...
I think the problem you encounter is due to the way you add the commandButton in the JSF component tree, or, to be more exact, the way uou do NOT add it in the component tree.
As you do not attach the commandButton to the JSF component tree, when this component is rendered (by your call to .encodeAll() method), it does not find the form where this component is nested.
Thus, the HTML input is not created correctly.
Maybe you can try to add the commandButton created to the form directly, before asking it to be rendered. You can do that with the following code:
note that I've tested this code, so maybe you have to modify it a little...
If it still doesn't work, maybe you will need to review you code in order to create the commandButton outside the render class or outside the encodeBegin... I don't think it is a good idea to modify the JSF components tree during the rendering phase...
您的代码似乎是正确的(事实上,该方法必须返回一个 String,但它也可以返回 void,即使不建议编写这样的操作方法)。
您确定创建的命令按钮嵌套在组件内吗? 否则,它将无法工作。
我的意思是,(无论是在 Java 还是 JSF 页面中创建的)必须有一个直接或间接的父组件(在 JSF 组件树中)。 例如:
您点击问题时是否出现Javascript错误?
编辑有关评论。
编辑2,关于我对主帖的评论:
也许您可以尝试用旧的方式将操作附加到按钮上(好吧,它已被弃用,但请尝试一下):
Your code seems to be correct (indeed, the method must return a String, but it can also return void, even if it is not recommanded to write an action method like that).
Are you sure that the commandButton created is nested within a component? Otherwise, it will not work.
By that, I mean that the (created in Java or JSF page, no matter), must have a direct or indirect parent (in the JSF component tree) a component. For example:
Have you any Javascript error when you click on the problem?
Edit regarding the comment.
Edit 2, regarding my comment on the main post:
Maybe you can try to attach the action on your button with the old way (ok, it is deprecated, but just give it a try):