I'm running in a little issue here regarding jsf related dropdown selection. I have 2 dropdown selection: the first one is independent, the second one shows result depending from This is the code:
关于jsf相关的下拉选择,我在这里遇到一个小问题。我有2个下拉选择:第一个是独立的,第二个显示结果取决于这是代码:
<h:panelGroup id="addressPanel">
<h:outputLabel styleClass="label" value="Provincia: " />
<h:selectOneMenu onchange="updateCombos()"
value="#{indirizzoCtrl.codiceProvincia}" >
<f:selectItem itemValue="" itemLabel=""></f:selectItem>
<f:selectItems value="#{indirizzoCtrl.allProvincia}" var="c"
itemLabel="#{c.nome}" itemValue="#{c.siglaProvincia}" />
</h:selectOneMenu>
<h:outputLabel styleClass="label" value="Comune: " />
<h:selectOneMenu
value="#{indirizzoCtrl.codiceComune}" >
<f:selectItem itemValue="" itemLabel=""></f:selectItem>
<f:selectItems value="#{indirizzoCtrl.allComuni}" var="c"
itemLabel="#{c.descrizione}" itemValue="#{c.codiceComune}" />
</h:selectOneMenu>
</h:panelGrid>
</h:panelGroup>
<p:remoteCommand name="updateCombos" update="addressPanel masterForm:msg" />
<p:commandButton styleClass="commandButton" value="Save"
actionListener="#{indirizzoCtrl.save}">
</p:commandButton>
Well, when the user save the form after selecting both the value, the managed bean indirizzoCtrl (request scoped) cannot map the value of the second dropdown back to the list, because there's no list. In fact the #{indirizzoCtrl.allComuni}
call a getter that retrieve the data from the DB only if indirizzoCtrl.codiceProvincia!=null
... and that's false before the update model phase. So the first time the getter for the list is called cannot retrieve any values, and that's bring the update model phase to fail. How can I handle this scenario... I think it's a pretty common one, so I'm missing something here...
好吧,当用户在选择了两个值后保存表单时,托管bean indirizzoCtrl(请求作用域)无法将第二个下拉列表的值映射回列表,因为没有列表。事实上,#{indirizzoCtrl.allComuni}调用一个getter,只有当indirizzoCtrl.codiceProvincia!= null时才从数据库中检索数据......并且在更新模型阶段之前这是假的。因此,第一次调用列表的getter时无法检索任何值,这会使更新模型阶段失败。我怎么能处理这个场景......我认为这是一个很常见的场景,所以我在这里遗漏了一些东西......
1 个解决方案
#1
5
Put the bean in the view scope instead. It will live as long as you're interacting with the same view by ajax. A request scoped bean get indeed recreated on every single request, also ajax requests, so bean properties would reinitialize to their defaults.
将bean放在视图范围中。只要你通过ajax与同一个视图进行交互,它就会存在。确实在每个请求上重新创建了一个请求范围的bean,也就是ajax请求,因此bean属性会重新初始化为它们的默认值。
@ManagedBean
@ViewScoped
public class IndidizzoCtrl implements Serializable {
// ...
}
See also:
- How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu
- 如何在更改h:selectOneMenu时加载和显示相关的h:selectOneMenu
- How to choose the right bean scope?
- 如何选择合适的bean范围?
Unrelated to the concrete problem, I also strongly recommend to change your getter methods to not do any business job, but just return data. Do the business job in (action)listener methods instead. E.g.
与具体问题无关,我还强烈建议改变你的getter方法,不做任何业务工作,只返回数据。而是在(动作)侦听器方法中执行业务工作。例如。
<h:selectOneMenu value="#{bean.menu1item}">
<f:selectItems value="#{bean.menu1items}" />
<f:ajax listener="#{bean.updateMenu2}" render="menu2" />
</h:selectOneMenu>
<h:selectOneMenu id="menu2" value="#{bean.menu2item}">
<f:selectItems value="#{bean.menu2items}" />
</h:selectOneMenu>
with
同
public void updateMenu2() {
menu2items = loadItBasedOn(menu1item);
}
See also:
- Why JSF calls getters multiple times
- 为什么JSF多次调用getter
#1
5
Put the bean in the view scope instead. It will live as long as you're interacting with the same view by ajax. A request scoped bean get indeed recreated on every single request, also ajax requests, so bean properties would reinitialize to their defaults.
将bean放在视图范围中。只要你通过ajax与同一个视图进行交互,它就会存在。确实在每个请求上重新创建了一个请求范围的bean,也就是ajax请求,因此bean属性会重新初始化为它们的默认值。
@ManagedBean
@ViewScoped
public class IndidizzoCtrl implements Serializable {
// ...
}
See also:
- How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu
- 如何在更改h:selectOneMenu时加载和显示相关的h:selectOneMenu
- How to choose the right bean scope?
- 如何选择合适的bean范围?
Unrelated to the concrete problem, I also strongly recommend to change your getter methods to not do any business job, but just return data. Do the business job in (action)listener methods instead. E.g.
与具体问题无关,我还强烈建议改变你的getter方法,不做任何业务工作,只返回数据。而是在(动作)侦听器方法中执行业务工作。例如。
<h:selectOneMenu value="#{bean.menu1item}">
<f:selectItems value="#{bean.menu1items}" />
<f:ajax listener="#{bean.updateMenu2}" render="menu2" />
</h:selectOneMenu>
<h:selectOneMenu id="menu2" value="#{bean.menu2item}">
<f:selectItems value="#{bean.menu2items}" />
</h:selectOneMenu>
with
同
public void updateMenu2() {
menu2items = loadItBasedOn(menu1item);
}
See also:
- Why JSF calls getters multiple times
- 为什么JSF多次调用getter