我在 JSF 中有以下基本的(也许是愚蠢的)理解问题:
有一个 JSF 页面“testPage.xhtml”:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:view>
<h:body>
<h:form>
<h:commandLink id="B1" value="B1" action="#{testBean.ctrl}"/>
<h:commandLink id="B2" value="B2" action="#{testBean.ctrl}"
rendered="#{testBean.renderB2}"/>
</h:form>
</h:body>
</f:view>
</html>
还有一个支持 bean“TestBean.java”:
package test;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean(name="testBean")
@RequestScoped
public class TestBean implements Serializable {
public static final long serialVersionUID = 1L;
private boolean renderB2 = false;
public String ctrl() {
setRenderB2(true);
System.out.println("ctrl() is called.");
return null;
}
public boolean getRenderB2() {
return renderB2;
}
public void setRenderB2(boolean renderB2) {
this.renderB2 = renderB2;
}
}
所以两个链接都有 TestBean.ctrl()
作为 Action 。
首先只渲染 B1
。单击 B1
会导致执行 TestBean.ctrl()
并且也会呈现 B2
。
但是,单击 B2
之后不会执行 TestBean.ctrl()
。
这就是我的问题:为什么单击 B2
时不执行 action 方法?
可能是因为 B2
没有再次渲染。但是为什么会阻止 action 方法的执行(由先前渲染的 B2
链接调用)?
最佳答案
那是因为 rendered
属性在表单提交的应用请求值阶段再次被重新评估。如果此时未呈现 UIInput
或 UICommand
组件,则 JSF 不会应用该组件的请求值。 IE。 UIInput
组件的模型值不会更新,UICommand
组件的操作也不会被调用。
因为您的 bean 是请求范围的,它在显示表单的响应结束时被丢弃,并且在表单提交请求开始时创建了一个全新的 bean。
您必须保留负责 rendered
属性的任何请求范围内的属性。最简单的方法是通过将 bean 标记为 @ViewScoped
并确保从操作方法返回 null
或 void
将其放置在 View 范围内应该回发到相同的 View 。
关于java - 使用请求范围的 bean 函数作为 JSF 中临时呈现按钮的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7012708/