我想修改PrimeFaces展示应用中的示例"ajaxify select",并根据第二个p:selectOneMenu
的选择引入第三个p:selectOneMenu
。
以下是修改后的代码:
<h:form>
<p:growl id="msgs" showDetail="true"/>
<p:panel header="Double Combo" style="margin-bottom:10px;">
<h:panelGrid columns="3" cellpadding="5">
<p:selectOneMenu id="city" value="#{pprBean.city}">
<f:selectItem itemLabel="Select City" itemValue="" />
<f:selectItems value="#{pprBean.cities}" />
<p:ajax update="suburbs"
listener="#{pprBean.handleCityChange}" />
</p:selectOneMenu>
<p:selectOneMenu id="suburbs" value="#{pprBean.suburb}">
<f:selectItem itemLabel="Select Suburb" itemValue="" />
<f:selectItems value="#{pprBean.suburbs}" />
<p:ajax update="subsuburbs"
listener="#{pprBean.handleSuburbChange}" />
</p:selectOneMenu>
<p:selectOneMenu id="subsuburbs" value="#{pprBean.subsuburb}">
<f:selectItem itemLabel="Select Subsuburb" itemValue="" />
<f:selectItems value="#{pprBean.subsuburbs}" />
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs"
actionListener="#{pprBean.displayLocation}"/>
</p:panel>
</h:form>
但是从不执行侦听器函数#{pprBean.handleSuburbChange}
。我在另一个论坛中看到,ajax响应中的动态代码不包含更新属性中指示的其他标记,但我该怎么办呢?
在PPRBean
代码中,我添加了:
@Named("pprBean")
@RequestScoped
public class PPRBean implements Serializable {
// ...
public void handleSuburbChange() {
if (suburb != null && !suburb.equals("")) {
subsuburbs = subsuburbsData.get(suburb);
} else {
subsuburbs = new HashMap<String, String>();
}
log.info("subsuburbs:" + subsuburbs);
}
// ...
答案 0 :(得分:0)
如果无法处理所选项目,则不会调用侦听器。您已将bean放在请求范围中,这意味着当与请求关联的响应完成时(即,当浏览器完成加载页面时),它就会被填充。因此,当您提交表单时,将触发一个新请求并创建一个全新的bean,在您的情况下,显然不会准备/预填充(post)构造函数中的郊区列表以查找所选项目(并执行监听器。)
要解决此问题,您通常需要通过JSF @ViewScoped
注释和@ManagedBean
将bean放在视图范围内。
@ManagedBean
@ViewScoped
public class Bean {
// ...
}
这样,只要您与同一视图交互,bean实例就会存在。但是当您使用CDI来管理bean而不是JSF时,您需要使用@ConversationScoped
代替并自己控制Conversation
。
@Named
@ConversationScoped
public class Bean {
@Inject
private Conversation conversation;
@PostConstruct
public void init() {
conversation.begin();
// ...
}
public void submit() {
// ...
conversation.end();
}
}