![](/img/trans.png)
[英]Value set by h:selectOneMenu is null in f:ajax listener method
[英]The f:ajax listener method in h:selectOneMenu is not executed
使用托管bean中的適當值正確生成頁面,但這兩個h:selectOneMenus中的ajax事件不起作用。 聽眾沒有被叫。 錯誤必須在標簽內的某處,但我沒有看到它。
<f:view>
<h:form>
<h:messages />
<h:panelGrid columns="3">
<h:outputLabel value="Choose your faculty: *" for="faculties" />
<h:selectOneMenu id="faculties" value="#{registrateStudent.selectedFaculty}" >
<f:ajax event="change" listener="#{registrateStudent.genSpecializations}" execute="faculties" render="specializations" />
<f:selectItems value="#{registrateStudent.listFaculty}" var="curFac" itemLabel="#{curFac.name}" itemValue="#{curFac}" />
</h:selectOneMenu>
<h:message id="message_faculties" for="faculties" />
<h:outputLabel value="Choose your specialization: *" for="specializations" />
<h:selectOneMenu id="specializations" value="#{registrateStudent.selectedSpecialization}" >
<f:selectItems value="#{registrateStudent.listSpecialization}" var="curSpec" itemLabel="#{curSpec.name}" itemValue="#{curSpec}"/>
</h:selectOneMenu>
<h:message id="message_specializations" for="specializations" />
托管Bean:
@ManagedBean(name = "registrateStudent")
@ViewScoped
public class RegistrateStudent {
private Faculty selectedFaculty;
private List<Faculty> listFaculty;
private Specialization selectedSpecialization;
private List<Specialization> listSpecialization;
private boolean showSpecialization = false;
/** Creates a new instance of RegistrateStudent */
public RegistrateStudent() {
users = new Users();
System.out.println("poaposd1");
student = new Student();
}
@PostConstruct
public void init() {
listFaculty = ff.findAll();
if (listFaculty != null) {
selectedFaculty = listFaculty.get(0);
listSpecialization = sf.findByFaculty(selectedFaculty.getIdFaculty());
if (listSpecialization != null) {
selectedSpecialization = listSpecialization.get(0);
}
else {}
} else {}
}
public void genSpecializations(AjaxBehaviorEvent event) {
if (sf.findByFaculty(selectedFaculty.getIdFaculty()) != null) {
this.showSpecialization = true;
} else {
JsfUtil.addSuccessMessage("faculties", "We don't have specializations for such faculty");
}
}
}
更新:
我發現了一些有趣的東西:
<f:ajax>
標記在<h:link>
, <h:selectOneMenu>
, <h:button>
, <h:commandButton>
。 在這種情況下,不會注意到render
屬性中的值不正確,但是event
屬性的值不正確會生成錯誤。
<h:outputLabel>
, <h:inputText>
<f:ajax>
正確使用<f:ajax>
<f:ajax>
要求jsf.js
文件包含在HTML <head>
。 它包含了用於執行JSF ajax魔術的所有JS函數。
要實現此目的,請確保在主模板中使用<h:head>
而不是<head>
。 然后,JSF將自動包含指向jsf.js
的必要<script>
元素。
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Look, with h:head</title>
</h:head>
<h:body>
Put your content here.
</h:body>
</html>
請注意,在一個有點像Web開發者工具集的網絡瀏覽器中,如Firefox的Web開發人員工具欄和/或Firebug,您應該立即注意到,當執行ajax請求時, jsf is undefined
等JS錯誤jsf is undefined
的。 至少應該考慮一些事情。
更新 :根據您的更新
我發現了一些有趣的東西:
<f:ajax>
標記在<h:link>
,<h:selectOneMenu>
,<h:button>
,<h:commandButton>
。 在這種情況下,不會注意到render
屬性中的值不正確,但是event
屬性的值不正確會生成錯誤。
<h:outputLabel>
,<h:inputText>
<f:ajax>
正確使用<f:ajax>
。
<h:link>
和<h:button>
僅用於GET請求,而不是POST請求。 但它應該可以在<h:selectOneMenu>
和<h:commandButton>
。 為簡單起見,您是否在問題中省略了完整圖片中的代碼? 你使用哪個JSF impl /版本? 你在classpath中使用正確的庫嗎? 看起來你必須搞砸了。
為了說服你(和我)我剛剛創建了以下copy'n'paste'n'runnable測試用例
<!DOCTYPE html>
<html lang="en"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:head>
<title>SO question 6089924</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu value="#{bean.selected}">
<f:selectItem itemValue="#{null}" itemLabel="Select..." />
<f:selectItem itemValue="one" />
<f:selectItem itemValue="two" />
<f:selectItem itemValue="three" />
<f:ajax listener="#{bean.listener}" render="result" />
</h:selectOneMenu>
<h:commandButton value="commandButton" action="#{bean.submit}">
<f:ajax listener="#{bean.listener}" render="result" />
</h:commandButton>
<h:outputText id="result" value="#{bean.selected} #{bean.result}" />
<h:messages />
</h:form>
</h:body>
</html>
用這個豆子
package com.example;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;
@ManagedBean
@ViewScoped
public class Bean implements Serializable {
private String selected;
private String result;
public void submit() {
System.out.println("submit");
}
public void listener(AjaxBehaviorEvent event) {
System.out.println("listener");
result = "called by " + event.getComponent().getClass().getName();
}
public String getSelected() {
return selected;
}
public void setSelected(String selected) {
this.selected = selected;
}
public String getResult() {
return result;
}
}
在Tomcat 7.0.12上,它可以與Mojarra 2.1.1一起運行。
INFO: Starting Servlet Engine: Apache Tomcat/7.0.12
INFO: Initializing Mojarra 2.1.1 (FCS 20110408) for context '/playground'
如果你有f:metadata
和f:viewparam
標記要小心,因為每個ajax請求都會調用參數的setter。
如果在調用ajax調用時出現任何錯誤/異常,是否可以提供錯誤日志?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.