h:selectOneMenu 中的 f:ajax 侦听器方法未执行



托管 Bean 中使用适当的值正确生成页面,但这两个 h:selectOneMenu 中的 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" />                    

托管豆:

@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>要求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浏览器中,有一个不错的Web开发人员工具集,如Firefox的Web开发人员工具栏和/或Firebug,你应该立即注意到JS错误,例如jsf is undefined执行ajax请求时。这至少应该有所考虑。

<小时 />更新

:根据您的更新

我发现了一些有趣的事情:

<f:ajax>标签在<h:link><h:selectOneMenu><h:button><h:commandButton> 上不起作用。在这种情况下render属性中的错误值不会被注意到,但属性event值不正确会生成错误。

<h:outputLabel><h:inputText>正确处理<f:ajax>

<h:link><h:button>仅用于 GET 请求,而不是 POST 请求。但是,它应该在<h:selectOneMenu><h:commandButton>上工作得很好。为了简单起见,您没有从问题中省略的更多代码进入整个图片吗?您使用的是哪个 JSF impl/版本?您是否在类路径中使用了正确的库?看起来你一定真的搞砸了什么。

为了说服你(和我自己),我刚刚创建了以下复制'n'粘贴'n'可运行的测试用例

<!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:metadataf:viewparam标签,请小心,因为每个 ajax 请求都会调用参数的 setter。

如果调用 ajax 调用时生成任何错误/异常,您能否提供错误日志?

相关内容

  • 没有找到相关文章

最新更新