环境:JSF 2.2与Mojarra 2.2.12& CDI ViewScoped beans& javax.faces.STATE_SAVING_METHOD
设置为client
。
为了通过<f:viewParam ... />
正确初始化我的bean,我希望(重新)执行<f:viewAction action="#{bean.onLoad}" />
当我的ViewScoped
bean 重新创建时(在POST请求之后,视图被从LRU推出,参见com.sun.faces.numberOfLogicalViews)。
<f:metadata>
<f:viewParam maxlength="100" name="name" value="#{bean.file}" />
<f:viewAction action="#{bean.onLoad}" />
</f:metadata>
<o:form includeRequestParams="true">
<!-- action can only work if onLoad has been called -->
<p:commandButton action="#{bean.action}" />
</o:form>
有什么想法吗?
注意:
postBack="true"
但不适合bean.onLoad()
会在每次 POST请求中调用。onLoad()
方法中调用@PostConstruct
,因为viewParam
尚未设置值(参见When to use f:viewAction versus PostConstruct?)。答案 0 :(得分:3)
我知道
onPostback
,但它不适合,因为每次POST请求都会调用bean.onLoad()。
您可以在<f:metadata>
<f:viewParam maxlength="100" name="name" value="#{bean.file}" required="true" />
<f:viewAction action="#{bean.onLoad}" onPostback="#{empty bean.file}" />
</f:metadata>
属性中使用EL,其中检查模型值和/或请求参数是否存在。
如果需要模型值,则只需检查它是否存在:
<f:metadata>
<f:viewParam maxlength="100" name="name" value="#{bean.file}" />
<f:viewAction action="#{bean.onLoad}" onPostback="#{empty bean.file and not empty param.name}" />
</f:metadata>
如果不需要模型值,则检查请求参数:
onLoad()
我无法在
@PostConstruct
方法中调用@PostConstruct
,因为viewParam尚未设置值。
鉴于您的代码段中存在<o:form>
,我发现您正在使用OmniFaces。同一个实用程序库提供了CDI @Param
注释,用于在<f:viewParam><f:viewAction>
运行之前注入,转换和验证HTTP请求参数。
因此可以替换整个@Inject @Param(name="name", validators="javax.faces.Length", validatorAttributes=@Attribute(name="maximum", value="100"))
private String file;
@PostConstruct
public void onLoad() {
if (!Faces.isValidationFailed()) {
// ...
}
}
,如下所示:
@Inject @Param(name="name") @Size(max=100)
private String file;
@PostConstruct
public void onLoad() {
if (!Faces.isValidationFailed()) {
// ...
}
}
或者如果你手头有Bean验证(又名JSR303):
for..in
答案 1 :(得分:0)
虽然我没有使用numberOfLogicalView,但我经常需要重新初始化具有较长生存范围的bean。例如,当用户在表视图中单击某个实体时,用例是(重新)从数据库加载一些详细数据。然后我只使用一些initialized
- 标志,例如
@SomeLongLivingScope
public class MyBean {
private boolean initialized = false;
public void preRenderView() {
if ( initialized ) return;
try {
do_init();
} finally {
initialized = true;
}
}
public void someDataChangedObserver( @Observes someData ) {
...
initialized = false;
}
}
使用此模式,您可以将viewAction与postBack="true"
一起使用。