在我的JSF视图中p:selectCheckboxMenu
,我想要通过AJAX对所选值执行某些业务逻辑.
对于一个简单的change
事件,它工作正常,但对于一个toggleSelect
事件没有.在我的监听器方法中,我正在检索旧的选择,但我期待这里的新选择.
请参阅以下示例:
@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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在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>
Run Code Online (Sandbox Code Playgroud)
现在让我们考虑以下用例:您正在进入视图,选择"一个"和"两个".如果我单击"全选"复选框,结果为:
Info: Current content of "list":
Info: one
Info: two
Run Code Online (Sandbox Code Playgroud)
但预期结果如下:
Info: Current content of "list":
Info: one
Info: two
Info: three
Run Code Online (Sandbox Code Playgroud)
对于常规更改事件,它按预期工作.在这里,我在听众中获得了新的选择.我该如何解决?或者我做错了什么?
GlassFish 4.1,在Java 1.8.0_45上运行
JSF 2.2.10(Mojarra)
PrimeFaces 5.1
OmniFaces 1.8.1
这个问题似乎与过早调用侦听器有关。通过进行一些基本的调试,我发现toggleSelect
在更新模型值之前调用侦听器方法,而change
事件在修改模型值之后执行此操作。这是我当前的代码:
请求Bean:
@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!");
}
}
Run Code Online (Sandbox Code Playgroud)
页面.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>
Run Code Online (Sandbox Code Playgroud)
这就是您当前步骤的跟踪:
Values set: [one]
Listener called!
Values set: [one, two]
Listener called!
Listener called!
Values set: [one, two, three]
Run Code Online (Sandbox Code Playgroud)
最后一个是toogle 选择,您可以看到模型已正确更新,但之前调用了侦听器。
让我们多玩一点自定义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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,模型值始终在UPDATE_MODEL_VALUES
阶段中设置,而change
事件INVOKE_APPLICATION
按其应有的方式执行,toggleSelect
监听器APPLY_REQUEST_VALUES
在列表中之前执行。
这似乎是 Primefaces 的一个 bug,应该在他们的 GitHub 分支中通知。
也可以看看:
归档时间: |
|
查看次数: |
14841 次 |
最近记录: |