我在新的JSF 2.1驱动的应用程序中使用复合,标记或自定义组件。
我仍然经常忽略正确(或至少推荐)的方式来继续使用这项技术。
当用户点击“保存”按钮时,我希望我的组件执行某些操作。实际上,保存按钮是Primefaces commandButton。
所以,我正在使用按钮代码,例如:
<p:commandButton id="example" type="submit" value="Confirmer les modifications" process="targetComponent" update="<compoents to update list>">
<f:param name="save" value="true>
</p:commandButton>
对于“保存”按钮,在我的组件中,我使用preRenderComponent来触发handleSubmit支持bean方法:
<f:event type="preRenderComponent" listener="#{myBeautifulBean.handleSubmit}"/>
handleSumit看起来像:
public void handleSubmit() {
FacesContext context = FacesContext.getCurrentInstance();
String saveMandats = JSFUtils.getRequestParameter("save");
if(context.isPostback() && !context.isValidationFailed() && (saveMandats != null) && !saveMandats.isEmpty())
confirmeModifsSelection();
}
有效 。
读取stackoverflow并尝试关注@BalusC建议,我使用omnifaces(1.2)并尝试使用postInvokeAction事件,原因在OmniFaces InvokeActionEventListener
showcase中解释。
所以,我正在将我的事件标记更改为:
<f:event type="postInvokeAction" listener="#{myBeautifulBean.handleSubmit}"/>
...永远不会调用myBeautifulBean.handleSubmit。
我当然是将omnifaces作为依赖项,其他组件(验证器等)才有效。 InvokeActionListener已正确初始化(或者对我来说似乎如此)。
postInvokeAction应该在特定时间注册吗?我注意到在omnifaces示例中,{pre | post} InvokeAction事件总是在f:metadata标签中声明为子项。
我发现很多例子,其中preRenderView事件在f:metadata之外声明,例如:http://www.mkyong.com/jsf2/jsf-2-prerenderviewevent-example/
顺便说一句,如果我这样做是完全错误的,我会很高兴从你的智慧中学习。但我想避免:
我正在寻找一种更加面向事件的方式。
答案 0 :(得分:1)
如上所述InvokeActionEventListener
showcase所示,此事件仅适用于UIViewRoot
,UIForm
,UIInput
和UICommand
。因此,如果您想要一个通用钩子(在视图上),那么您需要将它放在UIViewRoot
上。这需要将其放在<f:metadata>
。
preRenderComponent
和preRenderView
不需要特定的父组件,您实际上可以将其放置在视图中的任何位置,它始终会注册到最近的父UI组件。这对preInvokeAction
/ postInvokeAction
没有多大意义,因为没有每种类型的组件都参与调用操作。将其置于例如<h:panelGroup>
中并不是非常自我记录。