PrimeFaces selectCheckboxMenu:toggleSelect actionListener中的旧值 [英] PrimeFaces selectCheckboxMenu: Old values in toggleSelect actionListener

查看:119
本文介绍了PrimeFaces selectCheckboxMenu:toggleSelect actionListener中的旧值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的JSF视图中,我有一个p:selectCheckboxMenu,我想通过AJAX对所选值执行一些业务逻辑.

In my JSF view I have a p:selectCheckboxMenu where I want to perform some business logic via AJAX on the selected values.

对于简单的change事件,它可以正常工作,但对于toggleSelect事件,则不能.在我的侦听器方法中,我正在检索旧选择,但是我希望这里有新选择.

For a simple change event it works fine, but for a toggleSelect event not. Inside my listener method I am retrieving the old selection, but I am expecting the new selection here.

请参见以下示例:

@ViewScoped
@Named
public class RequestBean implements Serializable {
    private List<String> list; // + getter/setter

    @PostConstruct
    private void init() {       
        list = new ArrayList<String>() {{
          add("one");  add("two"); add("three");
        }};
    }

    public void listener() {
        System.out.println("Current content of \"list\":");
        for(String s : list) {
            System.out.println(s);
        }
    }
}

在JSF视图中:

<p:selectCheckboxMenu value="#{requestBean.list}" label="List">
    <f:selectItem itemValue="one" itemLabel="one"/>
    <f:selectItem itemValue="two" itemLabel="two"/>
    <f:selectItem itemValue="three" itemLabel="three"/>
    <p:ajax event="toggleSelect" listener="#{requestBean.listener}"  />
    <p:ajax event="change" listener="#{requestBean.listener}" />
</p:selectCheckboxMenu>

现在让我们考虑以下用例:您正在进入视图,选择了一个"和两个".如果我单击全选"复选框,结果是:

Now lets consider the following use-case: You are entering the view, "one" and "two" are selected. If I click the "select all" checkbox, the outcome is:

Info:   Current content of "list":
Info:   one
Info:   two

但是预期结果如下:

Info:   Current content of "list":
Info:   one
Info:   two
Info:   three

对于常规更改事件,它可以按预期运行.在这里,我在侦听器中得到了新的选择.我该如何解决?还是我做错了什么?

For the regular change event it works as expected. Here I am getting the new selection inside the listener. How may I fix it? Or what am I doing wrong?

在Java 1.8.0_45上运行的GlassFish 4.1

GlassFish 4.1, running on Java 1.8.0_45

JSF 2.2.10(Mojarra)

JSF 2.2.10 (Mojarra)

PrimeFaces 5.1

PrimeFaces 5.1

OmniFaces 1.8.1

OmniFaces 1.8.1

推荐答案

此问题似乎与过早调用侦听器有关.通过进行一些基本的调试,我发现toggleSelect在更新模型值之前调用了侦听器方法,而change事件在修改它们之后进行了调用.那是我当前的代码:

This issue seems to be related with the listener being called too early. Doing some basic debugging, I've found that toggleSelect invokes the listener method before updating the model values, while the change event does it after modifying them. That's my current code:

RequestBean:

@ViewScoped
@ManagedBean
public class RequestBean implements Serializable {
    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
        System.out.println("Values set: " + list);
    }

    private List<String> list;

    @PostConstruct
    private void init() {
        list = new ArrayList<String>() {
            {
                add("one");
                add("two");
                add("three");
            }
        };
    }

    public void listener() {
        System.out.println("Listener called!");
    }
}

page.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:comp="http://java.sun.com/jsf/composite/comp"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />
<h:body>
    <h:form>
        <p:selectCheckboxMenu value="#{requestBean.list}" label="List">
            <f:selectItem itemValue="one" itemLabel="one" />
            <f:selectItem itemValue="two" itemLabel="two" />
            <f:selectItem itemValue="three" itemLabel="three" />
            <p:ajax event="toggleSelect" listener="#{requestBean.listener}" />
            <p:ajax event="change" listener="#{requestBean.listener}" />
        </p:selectCheckboxMenu>
    </h:form>
</h:body>
</html>

这就是您当前步骤的踪迹:

And that's the trace for your current steps:

Values set: [one]
Listener called!
Values set: [one, two]
Listener called!
Listener called!
Values set: [one, two, three]

最后一个是toogle选择,因为您可以看到模型已正确更新,但之前已调用了侦听器.

The last one is the toogle selection, as you can see the model is properly updated, but the listener is called before.

让我们使用自定义的PhaseListener多玩一些:

Let's play a little bit more with a custom PhaseListener:

Entering RESTORE_VIEW 1
Entering APPLY_REQUEST_VALUES 2
Entering PROCESS_VALIDATIONS 3
Entering UPDATE_MODEL_VALUES 4
Values set: [one]
Entering INVOKE_APPLICATION 5
Listener called!
Entering RENDER_RESPONSE 6
Entering RESTORE_VIEW 1
Entering APPLY_REQUEST_VALUES 2
Entering PROCESS_VALIDATIONS 3
Entering UPDATE_MODEL_VALUES 4
Values set: [one, two]
Entering INVOKE_APPLICATION 5
Listener called!
Entering RENDER_RESPONSE 6
Entering RESTORE_VIEW 1
Entering APPLY_REQUEST_VALUES 2
Listener called!
Entering PROCESS_VALIDATIONS 3
Entering UPDATE_MODEL_VALUES 4
Values set: [one, two, three]
Entering INVOKE_APPLICATION 5
Entering RENDER_RESPONSE 6

如您所见,模型值始终在UPDATE_MODEL_VALUES阶段设置,而change事件在应有的INVOKE_APPLICATION中执行,toggleSelect侦听器在APPLY_REQUEST_VALUES中执行,而在APPLY_REQUEST_VALUES之前列表.

As you can see, the model values are always set in the UPDATE_MODEL_VALUES phase, while the change event performs in INVOKE_APPLICATION as it should, toggleSelect listener perform in APPLY_REQUEST_VALUES, which is before in the list.

这似乎是Primefaces错误,应在其GitHub分支中进行通知.

This seems to be a Primefaces bug, which should be notified in their GitHub branch.

另请参见:

这篇关于PrimeFaces selectCheckboxMenu:toggleSelect actionListener中的旧值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆