java JSF ValueChangeListener 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7956744/
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 22:10:57  来源:igfitidea点击:

JSF ValueChangeListener not working

javajspjsfevent-handling

提问by user1011376

I am learning how to use events with JSF. For some reason, the program is not changing the value in the text field when I change the value of the dropdown menu. The page loads and shows "Germany", but does not change the text field to "DE". Any suggestions?

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

Index.xhtml:

索引.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

我的Bean.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();
}

}

回答by BalusC

You're basically abusing the valueChangeListeneras an actionListener. The value change listener is intented to have access to boththe old and new value, right in between when the new input value is been submitted and the model value is been updated, so that you can for example add a log entry about the value change. You are apparently not interested in the old value. You're not interested in the value change event at all. You're only interested in the new model value. So you shouldn't be using the value change listener at all.

你基本上是在滥用valueChangeListener作为actionListener. 该值更改侦听器intented有机会获得这两个新旧价值,就在当新的输入值被提交和模型值进行了更新之间,这样就可以,例如增加约值变化的日志条目. 您显然对旧值不感兴趣。您对值更改事件根本不感兴趣。您只对新的模型值感兴趣。因此,您根本不应该使用值更改侦听器。

Normally, you'd like to do this job in an action listener method. You can use <f:ajax>to define an ajax action listener:

通常,您希望在动作侦听器方法中完成这项工作。您可以使用<f:ajax>来定义一个 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}" />

with

public void changeEvent() {
    selectedItem = selectedItem;
}

But since you've bound the input to the same property as the dropdown, the whole listener is superfluous. Just the following should do it for you:

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

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

The problem which you're seeing is because the onchange="submit()"essentially submits the wholeform, including all other input fields. As JSF processes input fields in sequence and you've bound the both fields to the same property, the value of <h:inputText>will override the value of <h:selectOneMenu>. As per my comment on the question, you would not have this problem when you made it a <h:inputText readonly="true">or a <h:outputText>(so that it won't submit its value to the server).

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

回答by Mechkov

Change this to output text component and see if it works

将此更改为输出文本组件并查看它是否有效

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

to

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

Regards!

问候!