【问题标题】:JSF ValueChangeListener not workingJSF ValueChangeListener 不工作
【发布时间】:2011-12-18 21:30:02
【问题描述】:

我正在学习如何在 JSF 中使用事件。出于某种原因,当我更改下拉菜单的值时,程序不会更改文本字段中的值。页面加载并显示“德国”,但不会将文本字段更改为“DE”。有什么建议吗?

索引.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:h="http://java.sun.com/jsf/html">
<h:head>
    <title>Facelet Title</title>
</h:head>
<h:body>
    <f:view>
        <h:form>
            <h:selectOneMenu value="#{Bean.selectedItem}" valueChangeListener="#{Bean.changeEvent}" onchange="submit()"  >
                <f:selectItems value="#{Bean.itemsList}" />
            </h:selectOneMenu>
            <br />
            <h:inputText value="#{Bean.selectedItem}" />
        </h:form>
    </f:view>
</h:body>

MyBean.java

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import java.util.ArrayList;
import javax.faces.model.SelectItem;
import javax.faces.event.ValueChangeEvent;
@ManagedBean (name = "Bean")
@RequestScoped
public class MyBean {

private static ArrayList menuItems;
private String selectedItem = "EN";
static {
    menuItems = new ArrayList();
    menuItems.add(new SelectItem("EN", "English"));
    menuItems.add(new SelectItem("DE", "Germany"));
}

public ArrayList getItemsList() {
    return this.menuItems;
}

public void setSelectedItem(String item) {
    this.selectedItem = item;
}

public String getSelectedItem() {
    return selectedItem;
}

public void changeEvent(ValueChangeEvent e) {
    selectedItem = e.getNewValue().toString();
}

}

【问题讨论】:

  • 那个输入字段真的需要是输入字段吗?它不应该是只读字段还是输出字段?
  • 我这样做只是为了了解它是如何工作的。我有另一个更大的程序,我使用它在选择时自动输入默认值。这是为了测试。我只需要弄清楚当下拉菜单值更改时如何更新文本字段。

标签: java jsp jsf event-handling


【解决方案1】:

您基本上是在滥用valueChangeListener 作为actionListener。值更改侦听器旨在访问同时旧值和新值,就在提交新输入值和更新模型值之间,例如,您可以添加关于值更改的日志条目。您显然对旧值不感兴趣。您根本对值更改事件不感兴趣。您只对新模型值感兴趣。所以你根本不应该使用值变化监听器。

通常,您希望在动作侦听器方法中完成这项工作。你可以使用&lt;f:ajax&gt;来定义一个ajax动作监听器:

<h:selectOneMenu value="#{Bean.selectedItem}">
    <f:selectItems value="#{Bean.itemsList}" />
    <f:ajax execute="@this" listener="#{Bean.changeEvent}" render="input" />
</h:selectOneMenu>
<h:inputText id="input" value="#{Bean.selectedItem}" />

与

public void changeEvent() {
    selectedItem = selectedItem;
}

但是由于您已将输入绑定到与下拉列表相同的属性,因此整个侦听器是多余的。只需以下内容即可为您完成:

<h:selectOneMenu value="#{Bean.selectedItem}">
    <f:selectItems value="#{Bean.itemsList}" />
    <f:ajax execute="@this" render="input" />
</h:selectOneMenu>
<h:inputText id="input" value="#{Bean.selectedItem}" />

您看到的问题是因为onchange="submit()" 实质上提交了整个 表单,包括所有其他输入字段。由于 JSF 按顺序处理输入字段并且您已将两个字段绑定到同一个属性,&lt;h:inputText&gt; 的值将覆盖&lt;h:selectOneMenu&gt; 的值。根据我对该问题的评论,当您将其设为 &lt;h:inputText readonly="true"&gt; 或 &lt;h:outputText&gt; 时,您不会遇到此问题(这样它就不会将其值提交给服务器)。

【讨论】:

    【解决方案2】:

    把这个改成输出文本组件,看看能不能工作

    <h:inputText value="#{Bean.selectedItem}" />
    

    到

    <h:outputText value="#{Bean.selectedItem}" />
    

    问候!

    【讨论】:

    • 那行得通。为什么它在输入文本字段上不起作用?该程序供用户选择他们的数据库引擎(MySQL、SQLServer、Oracle、PostgreSQL)。我需要在文本字段中放置一个默认端口,并允许用户在使用其他端口时编辑该字段。
    • 在这种情况下,您可以尝试将另一个侦听器绑定到 inputText 组件(如 onchange)。我强烈推荐使用 f:ajax 标签以及上面提到的其他海报。希望这行得通!
    猜你喜欢
    • 2012-07-25
    • 2011-04-05
    • 2011-09-16
    • 1970-01-01
    • 2011-06-15
    • 2011-05-29
    • 1970-01-01
    • 2011-04-26
    • 2016-08-02
    相关资源
    最近更新 更多