p:带onclick javascript钩子的按钮

时间:2016-05-12 16:17:47

标签: jsf primefaces

我正在使用p:按钮进行onclick操作。 (我无法转到p:commandButton,因为faces-config.xml中的遗留结果导航和db中的自定义导航历史记录):

<p:remoteCommand name="unlock_tt" actionListener="#{ttEntityMBean.unlock()}"/>
<p:button value="#{msgs['button.ok']}" outcome="#{ttEntityMBean.navigationMenuItemToRedirect.navigationRule}" onclick="unlock_tt()"/>

由primefaces生成javascript看起来像

onclick="unlock_tt(); window.open(....)"

点击按钮后,浏览器中的unlock_tt()启动了,但是立即被页面重定向破坏了,所以后面的java方法没有执行。 我应该让unlock_tt()或java调用async以确保它会在浏览器离开页面之前执行吗?

Upd:我想使用p:commandButton,如果有可能以编程方式获取to-view-id,就像这个问题一样:

Programmatically get navigation case <to-view-id> from faces-config.xml by outcome

<p:commandButton action="#{ttEntityBean.unlock()}"/>
public String unlock() {
  //some business logic
  return OutcomeResolverHelper.getRuleFor(navigationMenuItemToRedirect.navigationRule)
}

这应该减少请求数量

2 个答案:

答案 0 :(得分:0)

我不确定这会有效,但你可以试试这个:

而不是:

<p:remoteCommand name="unlock_tt" actionListener="#{ttEntityMBean.unlock()}"/>
<p:button value="#{msgs['button.ok']}" outcome="#{ttEntityMBean.navigationMenuItemToRedirect.navigationRule}" onclick="unlock_tt()"/>

做的:

<h:panelGroup>
<f:ajax event="click" listener="#{ttEntityMBean.unlock}"/>
<p:button value="#{msgs['button.ok']}" outcome="#{ttEntityMBean.navigationMenuItemToRedirect.navigationRule}" />
<h:panelGroup>

不要忘记删除onclick和你的远程命令。

这应该将panelGroup包裹在你的按钮周围。 PanelGroup实现了ClientBehaviorHolder,因此它可以在其子节点中获取f:ajax标记。因此,当您单击它时,它应该触发侦听器。

答案 1 :(得分:0)

最简单的方法是从p:按钮迁移到p:commandButton,它允许在重定向之前在action方法中执行一些java代码。核心是导航规则的程序化翻译,在faces-config.xml中定义为基本URL,可用于explisit jsf-2.0样式:

//receive base url from <to-view-id> tag
public static String resolveOutcomeRule(String ruleName) {
    FacesContext context = FacesContext.getCurrentInstance();
    ConfigurableNavigationHandler configNavHandler = (ConfigurableNavigationHandler)context.getApplication().getNavigationHandler();
    NavigationCase navCase = configNavHandler.getNavigationCase(context, null, ruleName);
    return navCase.getToViewId(context);
}
//decorate it with faces-redirect=true and our custom navigation
public static String resolveOutcome(NavigationMenuItem item) {
    return resolveOutcomeRule(item.getNavigationRule()) + "?faces-redirect=true&menu=" + item.getId();
}
//controller-method
public String cancelEditTT() {
    super.unlock();
    return FacesUtil.resolveOutcome(getNavigationMenuItemToRedirect());
}
//new jsf button:
<p:commandButton value="#{msgs['button.ok']}" action="#{ttEntityMBean.cancelEditTT}"/>

此解决方案提供了一步重定向,而不是两步旧重定向。