selectOneMenu选择后的JSF更新inputText
当我从selectOneMenu中选择另一个Skin时,我想更改inputTexts的值。 一切都很好,我的转换器从菜单中返回正确的对象,但inputTexts没有更新。selectOneMenu选择后的JSF更新inputText
<h:form>
<h:selectOneMenu id="dropdownSkin"
value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
onchange="this.form.submit()" converter="SkinConverter" >
<f:selectItems value="#{helloBean.mySkinsSI}" var="c"
itemValue="#{c.value}" />
</h:selectOneMenu>
<br />
<h:inputText id="name" value="#{helloBean.currentSkin.title}"></h:inputText>
<br />
<h:inputText id="tcolor" value="#{helloBean.currentSkin.titleBar.textColor}"></h:inputText>
<br />
<h:inputText id="bcolor" value="#{helloBean.currentSkin.titleBar.backgroundColorStart}"></h:inputText>
</h:form>
这是我的Bean的样子。我调试了它并且Object currentSkin设置正确。现在我需要知道如何更新文本框内容。
@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<ExtendedSkin> mySkins;
private List<SelectItem> mySkinsSI;
private ExtendedSkin currentSkin;
public void skinValueChanged(ValueChangeEvent e) {
currentSkin = (ExtendedSkin) e.getNewValue();
FacesContext.getCurrentInstance().renderResponse();
}
public List<ExtendedSkin> getMySkins() {
mySkins = XMLParser.readExtendedSkins();
return mySkins;
}
public List<SelectItem> getMySkinsSI() {
mySkinsSI = new LinkedList<SelectItem>();
for (ExtendedSkin s : getMySkins()) {
mySkinsSI.add(new SelectItem(s, s.getTitle()));
}
return mySkinsSI;
}
public void setMySkinsSI(List<SelectItem> myItems) {
this.mySkinsSI = myItems;
}
public ExtendedSkin getCurrentSkin() {
if (currentSkin == null) {
currentSkin = getMySkins().get(0);
}
return currentSkin;
}
public void setCurrentSkin(ExtendedSkin currentSkin) {
this.currentSkin = currentSkin;
}
}
这里的问题是,该转换器做它的工作填补了helloBean.currentSkin
对象,但是是有界的这一helloBean.currentSkin
在<h:inputText>
值:title
,textColor
和backgroundColorStart
将被发送到服务器并更换实际值由converter
加载。换句话说:
- 转换器被执行并基于所选值建立
helloBean.currentSkin
。 - 该
<h:inputText id="name">
空值被发送到服务器,并将被注入helloBean.currentSkin.title
。其他2<h:inputText>
s的行为相同。 - 该视图将使用所选的
helloBean.currentSkin
进行加载,并且它将使用空值加载helloBean.currentSkin.title
。其他2<h:inputText>
s的行为相同。
对于这个问题,有两种可能的解决方案:
-
移动
<h:inputText>
S中的形式之外,因此空值将不会被发送到服务器。加载视图时,它将保持加载在转换器中的值。<h:form> <h:selectOneMenu id="dropdownSkin" value="#{helloBean.currentSkin}" defaultLabel="Select a skin.." valueChangeListener="#{helloBean.skinValueChanged}" immediate="true" onchange="this.form.submit()" converter="SkinConverter" > <f:selectItems value="#{helloBean.mySkinsSI}" var="c" itemValue="#{c.value}" /> </h:selectOneMenu> </h:form> <br /> <h:inputText id="name" value="#{helloBean.currentSkin.title}"></h:inputText> <!-- rest of Facelets code... -->
-
既然你加载
helloBean.currentSkin
同时改变你的下拉列表选择的值,你可以在一个更清洁的方式添加使用<h:selectOneMenu>
内<f:ajax>
标签组成AJAX行为和更新的领域。我会选择这个解决方案。<h:form> <!-- Note that there's no need of the onchange JavaScript function --> <h:selectOneMenu id="dropdownSkin" value="#{helloBean.currentSkin}" defaultLabel="Select a skin.." valueChangeListener="#{helloBean.skinValueChanged}" immediate="true" converter="SkinConverter" > <f:selectItems value="#{helloBean.mySkinsSI}" var="c" itemValue="#{c.value}" /> <f:ajax process="@this" render="name tcolor bcolor" /> </h:selectOneMenu> <br /> <h:inputText id="name" value="#{helloBean.currentSkin.title}" /> <h:inputText id="tcolor" value="#{helloBean.currentSkin.titleBar.textColor}" /> <br /> <h:inputText id="bcolor" value="#{helloBean.currentSkin.titleBar.backgroundColorStart}" /> </h:form>
您可以了解更多关于<f:ajax>
在线教程像this one。
由于您要在页面中使用ajax调用,因此应该将托管bean范围从@SessionScoped
更改为@ViewScoped
。有关此处的更多信息,请执行以下操作:Communication in JSF 2
这个答案帮助我解决了我的问题:http:// stackoverflow。COM /问题/ 40182423 /改变输入型-ON-组合价值/ – user1156544 2016-10-22 15:43:18
尝试将“”移出窗体外(作为第一次尝试)。这应该工作 –
2013-02-22 16:12:30
Omg你做了thx :)发布它的答案,所以我可以接受它:) – 4ndro1d 2013-02-22 16:32:01
好吧,我会尽力解释问题和可能的解决方案。我在评论中提供的只是一个。 – 2013-02-22 16:36:15