我一直在我的应用中使用preRenderView(+重定向和跳过回发黑客),我试图用JSF2.2(MyFaces 2.2.4)附带的viewAction替换它。但是我发现它比命令actionListener和动作更早触发它对我的目的来说相当无用。例如:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class TestBean2 implements Serializable {
int count = 0;
public void actionFunc() {
System.out.println(count);
}
public String addCount() {
count++;
return null;
}
public int getCount() {
return count;
}
public void initView() {
System.out.println("initView");
}
public void setCount(int count) {
this.count = count;
}
}
然后是一个非常简单的.xhtml:
<!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:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" xmlns:pt="http://xmlns.jcp.org/jsf/passthrough" xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:t="http://myfaces.apache.org/tomahawk" xmlns:p="http://primefaces.org/ui">
<f:metadata>
<f:event type="preRenderView" listener="#{testBean2.initView}" />
<f:viewAction action="#{testBean2.actionFunc}" onPostback="true" />
</f:metadata>
<ui:composition template="/WEB-INF/template.xhtml">
<ui:define name="title">Test</ui:define>
<ui:define name="content">
#{testBean2.count}
<h:form>
<h:commandButton styleClass="btn btn-primary" action="#{testBean2.addCount}" value="addCount">
</h:commandButton>
</h:form>
</ui:define>
</ui:composition>
</html>
因此,addCount()System.out输出总是落后于渲染视图上的1,因为actionFunc()总是在addCount()之前触发。
如果我想做类似的事情,if(count == 3)做一个返回&#34; newpage&#34;对于重定向,它对于这样的决定来说太早了。我可以在initView()中进行检查并执行ConfigurableNavigationHandler.performNavigation(&#34; newpage&#34;),但这是我试图用JSF 2.2消除的那种黑客攻击。
因此,如果我希望它能够处理我将使用action或actionListener进行更改的任何值,那么viewAction似乎毫无用处。它应该像这样工作吗?
谢谢!
答案 0 :(得分:1)
preRenderView
事件is executed。但是,viewAction
标记不允许该阶段。我想在你的情况下,你应该在你的动作方法(TestBean2#addCount
)中处理重定向而忘记使用事件,因为对于刚刚初始化的值执行检查是没有意义的(&# 39;当您第一次加载视图时,使用preRenderView
方法执行的操作)。在执行了你的逻辑后,将它检入动作方法,似乎是它的自然方式。
我相信事件也可用于检查条件,但它们更多地与会话和应用程序状态有关,而与您当前的视图值无关。我的意思是,在您的视图呈现之前,当您的商店中没有可用的商品时,您可以执行此操作来处理重定向:
public String checkItemsAvailable() {
if (!dao.itemsAvailable()){
return "noItemsAvailable";
}
return null;
}
但是对于基于在当前视图中评估的条件的重定向,在动作方法中执行它是最好的方法:
public void addCount() {
count++;
if (count>3){
FacesContext.getCurrentInstance()
.getExternalContext().redirect("index.xhtml");
}
}
另见: