<h:selectBooleanCheckbox> 的值未根据辅助 bean 值更新
Value of <h:selectBooleanCheckbox> is not updated according to backing bean value
我正在使用 JSF2 和 Tomcat 服务器。我编写了一个简单的示例,其中:
- 用户从"h:selectOneMenu"
中选择教员
- 选择后,根据facultyNo
将"h:inputText"的值改为"odd"或"even"
- 此外,在选择时,如果 facultyNo 为偶数,"h:selectBooleanCheckBox" 的值更改为 "checked";如果 facultyNo 为奇数,则 "not checked" 的值更改为
"h:inputText" 一切正常。另一方面,"h:selectBooleanCheckBox" 的值不会改变。为什么会这样?
顺便说一下,在 HashMap 中使用布尔值是 故意的 因为我正在做的项目有很多HashMap 中的布尔值。因此,用一个简单的布尔值 属性 替换 Hashmap 并使用 getter 和 setter 绝对不是我的解决方案。
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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Dummy Title</title>
</head>
<body>
<h:form>
<label for="faculty">Faculty</label>
<h:selectOneMenu id="faculty" value="#{test.selectedFaculty}" converter="faccon" valueChangeListener="#{test.facultyChange}" onchange="submit()">
<f:selectItems value="#{start.app.faculties}"/>
</h:selectOneMenu>
<h:selectBooleanCheckbox id="mycheck" value="#{test.x.get(0)}"></h:selectBooleanCheckbox>
<h:outputText value="#{test.res}"></h:outputText>
<h:commandButton value="Save" action="#{test.saveChoices}" />
</h:form>
</body>
</html>
支持 bean 的代码如下
import java.io.Serializable;
import java.util.HashMap;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.ValueChangeEvent;
import com.myWork.Application;
import com.myWork.Faculty;
@ManagedBean(name="test")
@RequestScoped
public class TestBean implements Serializable
{
private HashMap<Integer,Boolean> x;
private String res;
private Faculty selectedFaculty;
@PostConstruct
public void init(){
Application app = Application.getInstance();
selectedFaculty = app.getFaculties()[0];
x = new HashMap<Integer, Boolean>();
if (selectedFaculty.getFacultyNo()%2==0)
{
x.put(0, true);
res = "even";
}
else
{
x.put(0, false);
res = "odd";
}
}
public HashMap<Integer,Boolean> getX() {
return x;
}
public void setX(HashMap<Integer,Boolean> x) {
this.x = x;
}
public Faculty getSelectedFaculty() {
return selectedFaculty;
}
public void setSelectedFaculty(Faculty selectedFaculty) {
this.selectedFaculty = selectedFaculty;
}
public String getRes() {
return res;
}
public void setRes(String res) {
this.res = res;
}
public void facultyChange(ValueChangeEvent e){
Faculty fac = (Faculty) e.getNewValue();
if (fac.getFacultyNo()%2==0)
{
x.put(0, true);
res = "even";
}
else
{
x.put(0, false);
res = "odd";
}
}
public String saveChoices(){
return "test";
}
}
非常感谢任何帮助。
为了将更新发送到不同的组件,您可以通过调用 Ajax 将参数发送到托管 bean 来利用部分页面呈现。
<h:selectBooleanCheckBox>
以内
<h:selectOneMenu id="faculty" value="#{test.selectedFaculty}" converter="faccon" valueChangeListener="#{test.facultyChange}">
<f:selectItems value="#{start.app.faculties}"/>
</h:selectOneMenu>
<h:selectBooleanCheckbox id="mycheck" valueChangeListener="#{test.facultyChange}" value="#{test.x.get(0)}">
<f:ajax event="change" execute="@form" render="faculty"/>
</h:selectBooleanCheckbox>
编辑: 删除了 selectOneMenu
中对 onSubmit()
的调用。在 selectBooleanCheckbox
中引入了 ajax 调用以进行部分页面刷新。
请参阅 this post.
处的完整解决方案
其实你的问题与JSF无关,与EL有关。在你的情况下,EL 将你的映射键视为 long
而不是 int
,因此你应该将映射更改为:
HashMap<Long, Boolean> map = new HashMap<>();
并按如下方式设置键值:
map.put(0L, false);
map.put(1L, true);
强制将其自动装箱到很长。
注意:问题在下面的问题中有详细描述:
EL access a map value by Integer key
我正在使用 JSF2 和 Tomcat 服务器。我编写了一个简单的示例,其中:
- 用户从"h:selectOneMenu" 中选择教员
- 选择后,根据facultyNo 将"h:inputText"的值改为"odd"或"even"
- 此外,在选择时,如果 facultyNo 为偶数,"h:selectBooleanCheckBox" 的值更改为 "checked";如果 facultyNo 为奇数,则 "not checked" 的值更改为
"h:inputText" 一切正常。另一方面,"h:selectBooleanCheckBox" 的值不会改变。为什么会这样?
顺便说一下,在 HashMap 中使用布尔值是 故意的 因为我正在做的项目有很多HashMap 中的布尔值。因此,用一个简单的布尔值 属性 替换 Hashmap 并使用 getter 和 setter 绝对不是我的解决方案。
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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Dummy Title</title>
</head>
<body>
<h:form>
<label for="faculty">Faculty</label>
<h:selectOneMenu id="faculty" value="#{test.selectedFaculty}" converter="faccon" valueChangeListener="#{test.facultyChange}" onchange="submit()">
<f:selectItems value="#{start.app.faculties}"/>
</h:selectOneMenu>
<h:selectBooleanCheckbox id="mycheck" value="#{test.x.get(0)}"></h:selectBooleanCheckbox>
<h:outputText value="#{test.res}"></h:outputText>
<h:commandButton value="Save" action="#{test.saveChoices}" />
</h:form>
</body>
</html>
支持 bean 的代码如下
import java.io.Serializable;
import java.util.HashMap;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.ValueChangeEvent;
import com.myWork.Application;
import com.myWork.Faculty;
@ManagedBean(name="test")
@RequestScoped
public class TestBean implements Serializable
{
private HashMap<Integer,Boolean> x;
private String res;
private Faculty selectedFaculty;
@PostConstruct
public void init(){
Application app = Application.getInstance();
selectedFaculty = app.getFaculties()[0];
x = new HashMap<Integer, Boolean>();
if (selectedFaculty.getFacultyNo()%2==0)
{
x.put(0, true);
res = "even";
}
else
{
x.put(0, false);
res = "odd";
}
}
public HashMap<Integer,Boolean> getX() {
return x;
}
public void setX(HashMap<Integer,Boolean> x) {
this.x = x;
}
public Faculty getSelectedFaculty() {
return selectedFaculty;
}
public void setSelectedFaculty(Faculty selectedFaculty) {
this.selectedFaculty = selectedFaculty;
}
public String getRes() {
return res;
}
public void setRes(String res) {
this.res = res;
}
public void facultyChange(ValueChangeEvent e){
Faculty fac = (Faculty) e.getNewValue();
if (fac.getFacultyNo()%2==0)
{
x.put(0, true);
res = "even";
}
else
{
x.put(0, false);
res = "odd";
}
}
public String saveChoices(){
return "test";
}
}
非常感谢任何帮助。
为了将更新发送到不同的组件,您可以通过调用 Ajax 将参数发送到托管 bean 来利用部分页面呈现。
<h:selectBooleanCheckBox>
<h:selectOneMenu id="faculty" value="#{test.selectedFaculty}" converter="faccon" valueChangeListener="#{test.facultyChange}">
<f:selectItems value="#{start.app.faculties}"/>
</h:selectOneMenu>
<h:selectBooleanCheckbox id="mycheck" valueChangeListener="#{test.facultyChange}" value="#{test.x.get(0)}">
<f:ajax event="change" execute="@form" render="faculty"/>
</h:selectBooleanCheckbox>
编辑: 删除了 selectOneMenu
中对 onSubmit()
的调用。在 selectBooleanCheckbox
中引入了 ajax 调用以进行部分页面刷新。
请参阅 this post.
其实你的问题与JSF无关,与EL有关。在你的情况下,EL 将你的映射键视为 long
而不是 int
,因此你应该将映射更改为:
HashMap<Long, Boolean> map = new HashMap<>();
并按如下方式设置键值:
map.put(0L, false);
map.put(1L, true);
强制将其自动装箱到很长。
注意:问题在下面的问题中有详细描述: EL access a map value by Integer key