Smu*_*tje 3 jsf jsf-2.2 viewaction
我们有一个设置,我们将不同的可选视图参数传递给JSF页面,并在设置参数后处理后续视图操作.一个非常简单的例子如下所示:
page.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:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<f:metadata>
<f:viewParam name="a" value="#{page.a}"/>
<f:viewAction action="#{page.populateA()}" if="#{not empty page.a}"/>
<f:viewParam name="b" value="#{page.b}"/>
<f:viewAction action="#{page.populateB()}"/>
</f:metadata>
<h:outputLabel value="#{page.message}"/>
</f:view>
</html>
Run Code Online (Sandbox Code Playgroud)
页
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@ViewScoped
@Named
public class Page {
private String a;
private String b;
private String message;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getMessage() {
return message;
}
public void populateA() {
this.message = "Param a given: " + this.a;
}
public void populateB() {
if (this.b != null) {
this.message = "Param b given: " + this.b;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,区别在于处理a
不起作用(page.xhtml?a = 123),而处理b
工作就像魅力(page.xhtml?b = 123) - 尽管我认为我只是移动了null-检查从Java到JSF.关于可读性,我宁愿在Java中省略额外的空值检查,并且将视图参数处理完全放在JSF中,但是如何调整代码以使第一个场景工作?
编辑根据接受的答案f:viewAction的渲染属性的目的是什么?,if
作品本身,所以我怀疑是错误的执行顺序(先评估行动的条件,那么值适用于模型).
该<f:viewAction if>
属性基本上是一个重命名的<h:xxx rendered>
属性(我将留在中间不管是更清晰与否,它至少有一个自动生成的文件中错误的结果;它列出rendered
来代替if
),并具有因此正好在其他的期间相同的生命周期将"请求值"阶段应用为所有其他UI组件.此阶段调用UIComponent#decode()
视图中的所有UI组件.对于标签UIViewAction
后面的UI组件类<f:viewAction>
,decode()
描述如下:
如果满足以下任一条件,请不要采取任何措施:
当前请求是回发,并且实例已配置为不在回发上运行.见
isOnPostback()
.
if
财产中陈述的条件评估为假.看到isRendered()
所以,是的,你对"错误的执行顺序"确实是对的.在" 应用请求值"阶段,它会检查if
属性以及是否进行评估false
,然后不会进行解码,并且不会对操作事件进行排队.另请参阅UIViewAction
源代码的第644行,它测试isRendered()
insice decode()
,如果不执行则不会继续false
.在您的情况下,#{page.a}
您正在检查的<f:viewAction if>
,仅在" 更新模型值"阶段(即" 应用请求值"阶段之后)可用.
您希望测试在" 申请请求值"阶段期间保证可用的其他内容.最佳候选者将是实际的请求参数本身.所有"普通"请求参数都在EL范围内,隐式EL对象 使用参数名称作为键#{param}
引用a Map<String, String>
.
总而言之,这应该做到:
<f:viewParam name="a" value="#{page.a}"/>
<f:viewAction action="#{page.populateA}" if="#{not empty param.a}"/>
Run Code Online (Sandbox Code Playgroud)
更新解决的直观行为<f:viewAction if>
,JSF工具库OmniFaces将自2.2版提供的<o:viewAction>
,其if
时只计算调用应用程序阶段,被广播的操作事件之前的权利.这个技巧是通过简单地扩展UIViewAction
组件并覆盖它来完成的broadcast()
,isRendered()
如下所示:
@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (super.isRendered()) {
super.broadcast(event);
}
}
@Override
public boolean isRendered() {
return !isImmediate() || super.isRendered();
}
Run Code Online (Sandbox Code Playgroud)
这允许您更直观地使用标记:
<f:viewParam name="a" value="#{page.a}"/>
<o:viewAction action="#{page.populateA}" if="#{not empty page.a}"/>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2229 次 |
最近记录: |