java JSF 2 - f:ajax 标签不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3476588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:59:55  来源:igfitidea点击:

JSF 2 - f:ajax tag doesn't work

javaajaxfaceletsjsf-2

提问by user219882

I have a problem with f:ajax tag. In my previous project, everything worked perfectly. Now I have another project and f:ajax tag doesn't work at all and I don't know why.

我有 f:ajax 标签的问题。在我之前的项目中,一切正常。现在我有另一个项目,f:ajax 标签根本不起作用,我不知道为什么。

I have this in JSF page with Facelets:

我在带有 Facelets 的 JSF 页面中有这个:

<h:form>
...
    <h:selectOneMenu id="employeeId" value="#{employeeBean.employeeId}">
        <f:selectItems value="#{employeeBean.employeesSelectItem}"/>
        <f:ajax event="change" listener="#{employeeBean.changeOwner}"/>
     </h:selectOneMenu>
...
</h:form>

And employeeBean with changeOwner method with database access:

以及具有数据库访问权限的具有 changeOwner 方法的employeeBean:

...
public void changeOwner(AjaxBehaviorEvent event) {
    try {
        update.updateOwner(...params...);
        JSF.setMessage(Messages.UPDATE_OK);
    } catch (UpdateDBException ex) {
        JSF.setMessage(ex.getMessage());
    }
}
...

I can't see anything wrong. Thanks for help.

我看不出有什么不妥。感谢帮助。

UPDATE

更新

faces-config:

面孔配置:

<faces-config version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

    <converter>
        <converter-for-class>java.util.Date</converter-for-class>
        <converter-class>misc.TimeZoneConverter</converter-class>
    </converter>
</faces-config>

xhtml page:

xhtml页面:

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
            template="./../templates/mainTemplate.xhtml"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core">

<ui:define name="content">
    <h2>Smazání zaměstnance</h2>
            Proto?e s danym zaměstnancem (#{employeeBean.employee.name} #{employeeBean.employee.surname}) souvisejí některé úkoly, je pot?eba, aby se jich ujal jiny. Vyberte prosím nové zaměstnance u v?ech ní?e uvedenych úkol?.
            <h:form>
                <h:dataTable value="#{taskBean.employeeTasks}" var="item">
                    <h:column>
                        <f:facet name="header">ID</f:facet>
                        <center>#{item.idtask}</center>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Zadavatel</f:facet>
                        <h:selectOneMenu id="managerId" value="#{employeeBean.newManagerId}" rendered="#{employeeBean.employeeId == item.employeeByIdmanager.idemployee}">
                            <f:selectItems value="#{employeeBean.otherEmployeesSelectItem}"/>
                            <f:ajax event="change" listener="#{employeeBean.changeOwner}"/>
                        </h:selectOneMenu>
                        <h:outputText value="#{item.employeeByIdmanager.name} #{item.employeeByIdmanager.surname}" rendered="#{employeeBean.employeeId != item.employeeByIdmanager.idemployee}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Zodpovědná osoba</f:facet>
                        <h:selectOneMenu id="employeeId" value="#{employeeBean.newEmployeeId}" rendered="#{employeeBean.employeeId == item.employeeByIdemployee.idemployee}">
                            <f:selectItems value="#{employeeBean.otherEmployeesSelectItem}"/>
                            <f:ajax event="change" listener="#{employeeBean.changeOwner}"/>
                        </h:selectOneMenu>
                        <h:outputText value="#{item.employeeByIdemployee.name} #{item.employeeByIdemployee.surname}" rendered="#{employeeBean.employeeId != item.employeeByIdemployee.idemployee}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header">?as zadání</f:facet>
                        <center><h:outputText value="#{item.timestart}"/></center>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Udělat do</f:facet>
                        <center><h:outputText value="#{item.timetodo}"/></center>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Popis úkolu</f:facet>
                        #{item.text}
                    </h:column>
                    <h:column>
                        <f:facet name="header">Zákazník</f:facet>
                        <h:link outcome="viewCustomerDetails">
                            <h:panelGrid columns="1">
                                <h:outputText value="#{item.customer.name}"/>
                                <h:outputText value="#{item.customer.addresscity}"/>
                            </h:panelGrid>
                            <f:param name="customerId" value="#{item.customer.idcustomer}"/>
                        </h:link>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Stav úkolu</f:facet>
                        #{item.taskstate.state}
                    </h:column>
                    <h:column>
                        <f:facet name="header">Poznámky</f:facet>
                        <h:outputText escape="false" value="#{item.note}"/>
                    </h:column>
                </h:dataTable>
            </h:form>

    <h:messages globalOnly="true" styleClass="messages"/>
</ui:define>

UPDATE2

更新2

EmployeeBean:

员工豆:

package beans;
import beans.jsf.JSF;
import ejb.Get;
import ejb.Update;
import entities.Employee;
import entities.Permission;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.model.SelectItem;
import javax.validation.constraints.Pattern;
import misc.Messages;

@ManagedBean(name="employeeBean")
@RequestScoped
public class EmployeeBean {

@EJB
private Get get;

@EJB
private Update update;

@ManagedProperty(name="employeeId", value="#{param['employeeId']}")
private int employeeId;

private int newManagerId;

private int newEmployeeId;

private String edit = "none";

@Pattern(regexp=".+", message="Jméno musí byt vyplněno.")
private String name;

@Pattern(regexp=".+", message="P?íjmení musí byt vyplněno.")
private String surname;

private int permissionId;

private Employee employee;

/** Creates a new instance of EmployeeBean */
public EmployeeBean() {
}

public int getNewEmployeeId() {
    return newEmployeeId;
}

public void setNewEmployeeId(int newEmployeeId) {
    this.newEmployeeId = newEmployeeId;
}

public int getNewManagerId() {
    return newManagerId;
}

public void setNewManagerId(int newManagerId) {
    this.newManagerId = newManagerId;
}

public int getEmployeeId() {
    return employeeId;
}

public void setEmployeeId(int employeeId) {
    this.employeeId = employeeId;
    employee = get.getEmployee(employeeId);
}

public String getEdit() {
    return edit;
}

public void setEdit(String edit) {
    this.edit = edit;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getPermissionId() {
    return permissionId;
}

public void setPermissionId(int permissionId) {
    this.permissionId = permissionId;
}

public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}

public Employee getEmployee() {
    return employee;
}

public void setEmployee(Employee employee) {
    this.employee = employee;
}

private void showEdit() {
    edit = "block";
}

private void hideEdit() {
    edit = "none";
}

/**
 * Naplní SelectItem v?emi zaměstnanci.
 * @return seznam zaměstnanc?
 */
public List<SelectItem> getEmployeesSelectItem() {
    List<SelectItem> employees = new ArrayList<SelectItem>();

    for (Employee e : get.getEmployees()) {
        employees.add(new SelectItem(e.getIdemployee(), e.getName() + " " + e.getSurname()));
    }

    return employees;
}

/**
 * Vrátí seznam zákazník?.
 * @return seznam zákazník?
 */
public List<Employee> getEmployees() {
    return get.getEmployees();
}


/**
 * Na?te úkol pro editaci.
 */
public void loadEmployee() {
    Employee e = get.getEmployee(employeeId);

    if (e != null) {
        name = e.getName();
        surname = e.getSurname();
        permissionId = e.getPermission().getIdpermission();

        showEdit();
    } else {
        JSF.setMessage(Messages.DB_RETURN_NULL);
    }
}

/**
 * Naplní SelectItem v?emi oprávněními.
 * @return seznam oprávnění
 */
public List<SelectItem> getPermissionsSelectItem() {
    List<SelectItem> permissions = new ArrayList<SelectItem>();

    for (Permission p : get.getPermissions()) {
        permissions.add(new SelectItem(p.getIdpermission(), p.getPermissionname()));
    }

    return permissions;
}    

/**
 * Zapí?e úpravy úkolu.
 */
public void updateEmployee() {
    try {
        update.updateEmployee(name, surname, employeeId, permissionId);
        JSF.setMessage(Messages.EMPLOYEE_UPDATE_OK);
    } catch (Exception ex) {
        showEdit();
        JSF.setMessage(ex.getMessage());
    } 
}

/**
 * Zru?í prováděné úpravy a skryje editaci.
 */
public void cancel() {
    hideEdit();
}

public void changeOwner(int taskId) {
    System.out.println("taskId: "+taskId);
    System.out.println("managerId: "+newManagerId);
    System.out.println("employeeId: "+newEmployeeId);
//        try {
//            update.updateOwner(taskId, newManagerId, newEmployeeId);
//            JSF.setMessage(Messages.UPDATE_OK);
//        } catch (UpdateDBException ex) {
//            JSF.setMessage(ex.getMessage());
//        }
}

/**
 * Naplní SelectItem v?emi mo?nymi stavy pro úkol.
 * @return seznam stav? úkolu
 */
public List<SelectItem> getOtherEmployeesSelectItem() {
    List<SelectItem> employees = new ArrayList<SelectItem>();

    for (Employee e : get.getOtherEmployees(employeeId)) {
        employees.add(new SelectItem(e.getIdemployee(), e.getName() + " " + e.getSurname()));
    }

    return employees;
}
}

回答by BalusC

This will only work when the input element is inside a form. So put the whole menu in a <h:form>.

这仅在输入元素位于表单内时才有效。所以把整个菜单放在一个<h:form>.



Update:the f:ajaxis in fact a JSF 2.0 tag. If you ever change your JSF libs or the faces-config.xmlto comply JSF 1.2, then the f:ajaxwill stop working. Verify if you're using the correct versioned libs and the root declaration of any faces-config.xmlis set to JSF 2.0.

更新:f:ajax,其实是JSF 2.0标签。如果您更改了 JSF 库或faces-config.xml使其符合 JSF 1.2,那么f:ajax它将停止工作。验证您是否使用了正确的版本化库,并且 any 的根声明faces-config.xml设置为 JSF 2.0。

If that doesn't help, then I don't see other causes than that you aren't running the code you think you're running. Did you read the server logs? Did you run the debugger? Did you eliminate the surrounding code so that the JSF page ends up with onlythe code as in your question inside the h:body?

如果这没有帮助,那么除了您没有运行您认为正在运行的代码之外,我看不出其他原因。你读过服务器日志吗?你运行调试器了吗?您是否消除了周围的代码,以便 JSF 页面最终包含您在h:body.



Update 2:the EmployeeBeanis set as @RequestScopedwhich means that it's garbaged at end of request (after sending the response). The loading of the employee is depending on the presence of an employee ID which is been set as a request parameter. Basically you need to pass the employee ID on everyrequest to get the employee to load, including ajaxical requests. Also, the rendering of the dropdown is depending on the presence of a valid employee in the request. If the rendered condition evaluates falseduring ajaxical request, the ajax action won't be invoked. I am not sure about this complex case, but in theory passing the employee ID as hidden parameter should help:

更新2:EmployeeBean被设置为@RequestScoped,这意味着它在请求端garbaged(发送响应之后)。员工的加载取决于设置为请求参数的员工 ID 的存在。基本上,您需要在每个请求上传递员工 ID才能让员工加载,包括 ajaxical 请求。此外,下拉列表的呈现取决于请求中是否存在有效员工。如果渲染条件false在 ajax 请求期间求值,则不会调用 ajax 操作。我不确定这个复杂的情况,但理论上将员工 ID 作为隐藏参数传递应该会有所帮助:

<h:inputHidden value="#{employeeBean.employeeId}" />

Put it in the form next to the table.

把它放在桌子旁边的表格里。

回答by Dejell

Since f:ajaxlistenerexpects to AjaxBehaviorEvent

由于f:ajaxlistener预计AjaxBehaviorEvent

change it to:

将其更改为:

public void changeOwner(AjaxBehaviorEvent event) {
    try {
        update.updateOwner(...params...);
        JSF.setMessage(Messages.UPDATE_OK);
    } catch (UpdateDBException ex) {
        JSF.setMessage(ex.getMessage());
    }
}

EDITED: Check if any other component in the form blocks the form from being submitted. (Maybe h:selectonemenu etc.)

已编辑:检查表单中的任何其他组件是否阻止提交表单。(也许 h:selectonemenu 等)