简体   繁体   English

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

[英]The f:ajax listener method in h:selectOneMenu is not executed

The page is generated correctly with appropriate values in managed bean, but ajax events in these two h:selectOneMenus don't works. 使用托管bean中的适当值正确生成页面,但这两个h:selectOneMenus中的ajax事件不起作用。 Listener is not called. 听众没有被叫。 An error has to be somewhere within tags, but I don't see it. 错误必须在标签内的某处,但我没有看到它。

<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" />                    

Managed Bean: 托管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");
        }
    }
}

UPDATE: 更新:

I've found out a few interesting things: 我发现了一些有趣的东西:

<f:ajax> tag doesn't work at <h:link> , <h:selectOneMenu> , <h:button> , <h:commandButton> . <f:ajax>标记在<h:link><h:selectOneMenu><h:button><h:commandButton> In this cases incorrect values in render attribute is not noticed, but incorrect value of event attribute generate an error. 在这种情况下,不会注意到render属性中的值不正确,但是event属性的值不正确会生成错误。

<h:outputLabel> , <h:inputText> work with <f:ajax> properly <h:outputLabel><h:inputText> <f:ajax>正确使用<f:ajax>

The <f:ajax> requires jsf.js file being included in the HTML <head> . <f:ajax>要求jsf.js文件包含在HTML <head> It contains all JS functions for doing the JSF ajax magic. 它包含了用于执行JSF ajax魔术的所有JS函数。

To achieve this, ensure that you're using <h:head> instead of <head> in the master template. 要实现此目的,请确保在主模板中使用<h:head>而不是<head> JSF will then automatically include the necessary <script> element there pointing to jsf.js . 然后,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>

Note that in a bit decent webbrowser with a bit decent webdeveloper toolset like Firefox's Web Developer Toolbar and/or Firebug you should immediately have noticed JS errors like jsf is undefined when the ajax request is to be executed. 请注意,在一个有点像Web开发者工具集的网络浏览器中,如Firefox的Web开发人员工具栏和/或Firebug,您应该立即注意到,当执行ajax请求时, jsf is undefined等JS错误jsf is undefined的。 That should at least have given something to think about. 至少应该考虑一些事情。


Update : as per your update 更新 :根据您的更新

I've found out a few interesting things: 我发现了一些有趣的东西:

<f:ajax> tag doesn't work at <h:link> , <h:selectOneMenu> , <h:button> , <h:commandButton> . <f:ajax>标记在<h:link><h:selectOneMenu><h:button><h:commandButton> In this cases incorrect values in render attribute is not noticed, but incorrect value of event attribute generate an error. 在这种情况下,不会注意到render属性中的值不正确,但是event属性的值不正确会生成错误。

<h:outputLabel> , <h:inputText> work with <f:ajax> properly. <h:outputLabel><h:inputText> <f:ajax>正确使用<f:ajax>

The <h:link> and <h:button> are intented for GET requests only, not POST requests. <h:link><h:button>仅用于GET请求,而不是POST请求。 It should however work just fine on <h:selectOneMenu> and <h:commandButton> . 但它应该可以在<h:selectOneMenu><h:commandButton> Don't you have more code into the complete picture which you omitted from the question for simplicity? 为简单起见,您是否在问题中省略了完整图片中的代码? Which JSF impl/version are you using? 你使用哪个JSF impl /版本? Are you using the right libraries in classpath? 你在classpath中使用正确的库吗? It look like that you must really have messed up something. 看起来你必须搞砸了。

To convince you (and myself) I just created the following copy'n'paste'n'runnable testcase 为了说服你(和我)我刚刚创建了以下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>

with this bean 用这个豆子

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;
    }

}

It runs fine with Mojarra 2.1.1 on Tomcat 7.0.12. 在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'

Be careful if you have f:metadata and f:viewparam tags since the setters of the parameters will be called with every ajax request. 如果你有f:metadataf:viewparam标记要小心,因为每个ajax请求都会调用参数的setter。

Can you provide the error log if there is any error/exception that is being generated when you call the ajax call? 如果在调用ajax调用时出现任何错误/异常,是否可以提供错误日志?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM