PrimeFaces p:ajax event="change" 不会在动态创建的 selecOneMenu 内容上触发

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

PrimeFaces p:ajax event="change" not fired on dynamically created selecOneMenu content

ajaxjakarta-eeprimefacesselectonemenu

提问by Hesi

I want to generate selecOneMenu content when the user types in an inputText field, and respond to combo box selection changes.
The below code updates the contents of the selecOneMenu as the user types. (The typed and the next 9 numbers gets added to the combo box. This is just a simplified example code.)
When the page is loaded, the change event of the selecOneMenu correctly gets fired. However after typing in the inputValue field, content of selecOneMenu is changed, and the change event is not fired when I select an item.

我想在用户输入 inputText 字段时生成 selecOneMenu 内容,并响应组合框选择更改。
下面的代码在用户输入时更新 selecOneMenu 的内容。(键入的和接下来的 9 个数字被添加到组合框中。这只是一个简化的示例代码。)
加载页面时,会正确触发 selecOneMenu 的更改事件。但是在 inputValue 字段中输入后, selecOneMenu 的内容发生了变化,并且当我选择一个项目时不会触发更改事件。

The code works if ComboBean is session scoped, but I want to avoid this solution if possible.

如果 ComboBean 是会话范围的,则代码有效,但如果可能,我想避免使用此解决方案。

Is it possible at all to do this?
What is the reason if it is not possible with request scope?

有可能做到这一点吗?
如果请求范围不可能,原因是什么?

PrimeFaces 2.2
Mojarra 2.0.2
GlassFish 3.0.1
Browser: Chrome, Firefox, IE

PrimeFaces 2.2
Mojarra 2.0.2
GlassFish 3.0.1
浏览器:Chrome、Firefox、IE

combo.xhtml:

组合.xhtml:

<h:head>
    <title>Combo box example</title>
</h:head>

<h:body>
    <h:form>
        <p:panel id="mainPanel">
            <h:panelGroup id="formToSubmit" layout="block">
                <p:messages id="messages" />
                <h:panelGrid columns="2">
                    <h:outputLabel value="Enter a number" />
                    <h:inputText id="inputValue" value="#{comboBean.inputValue}">
                        <p:ajax event="keyup" update="combo"
                            listener="#{comboBean.onKeyUp}" />
                    </h:inputText>

                    <h:outputLabel value="Select a value:" />
                    <h:selectOneMenu id="combo" value="#{comboBean.selectedValue}">
                        <f:selectItem itemLabel="Select a value..."
                            noSelectionOption="true" />
                        <f:selectItems value="#{comboBean.values}" />
                        <p:ajax event="change" update="selectedValue"
                            listener="#{comboBean.valueSelected}" />
                    </h:selectOneMenu>
                    <h:outputLabel value="Selected value:" />
                    <h:inputText id="selectedValue" value="#{comboBean.selectedValue}" />
                </h:panelGrid>
            </h:panelGroup>
        </p:panel>
    </h:form>
</h:body>
</html>

ComboBean.java

组合Bean.java

package x;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class ComboBean implements Serializable
{
    private static final long serialVersionUID = 1L;
    private String inputValue;
    private String selectedValue;
    private List<String> values;

    @PostConstruct
    void init()
    {
        System.out.println("init");
        setValues(new LinkedList<String>());
        for(int i = 0; i<10 ; i++)
        {
            getValues().add(""+i);
        }
    }

    public void onKeyUp()
    {
        System.out.println("onkeyUp " + getInputValue());
        setValues(new LinkedList<String>());
        if (inputValue != null)
        {
            try 
            {
                int v = Integer.parseInt(inputValue);
                for(int i = 0; i<10 ; i++)
                {
                    getValues().add(""+(v+i));
                }
            } 
            catch (NumberFormatException ne) 
            {
                //doesn't matter
            }
        }
    }

    public void valueSelected()
    {
        System.out.println("valueSelected " + getSelectedValue());
    }

    public void submit()
    {
        System.out.println("submit " + getInputValue());
    }

    public void setInputValue(String inputValue)
    {
        this.inputValue = inputValue;
    }

    public String getInputValue()
    {
        return inputValue;
    }

    public void setSelectedValue(String selectedValue)
    {
        this.selectedValue = selectedValue;
    }

    public String getSelectedValue()
    {
        return selectedValue;
    }

    public void setValues(List<String> values)
    {
        this.values = values;
    }

    public List<String> getValues()
    {
        return values;
    }

}

回答by Matt Handy

The problem is that you reset your list during each request in the init()method. So your selected element will no longer be there.

问题是您在init()方法中的每个请求期间都重置了您的列表。所以你选择的元素将不再存在。

If you don't want to use SessionScope, maybe the ViewScopewould be a solution: then the bean won't be reset if the same page is reloaded.

如果您不想使用SessionScope,也许这ViewScope将是一个解决方案:如果重新加载同一页面,则该 bean 将不会被重置。