首页 > 解决方案 > JSF 命令按钮 F 参数在 AJAX 重新呈现按钮时丢失 - 解决方法 ActionListener

问题描述

我正面临着——而且我相信这不是第一次——JSF 复合组件重新渲染的痛苦。

我面临的问题听起来与以下内容几乎相同: https ://forum.primefaces.org/viewtopic.php?t=27870

本质上,我正在将应用程序从全页导航重新转换为 ajax 导航,以避免重新加载 javascripts 等...

所以这个应用程序有一个底部导航菜单,其中每个按钮本质上都是复合组件

composite:implementation

基于primefaces

p:commandButton

这些按钮过去是非 ajax 的,定义了 action 属性并作为要导航到的新 XHTML 页面的操作的输出返回。你会得到整页,就是这样。

现在,如果我们启用基于 ajax 的导航,我们会得到一个漂亮的小 ajax p:commandd 按钮。

<myTagLib:commandButton id="btn_#{pl.newPageLinkKey}" title="#{i18n.static[pl.newPageLinkKey]}"
                action="#{box001.navigateToPageAjax}"
                disabled="#{box001.selectedBoxPageLink eq pl.pageLink ? true : false}"
                icon="#{box001.getIconByKey(pl.newPageLinkKey)}" value="#{i18n.static[pl.newPageLinkKey]}"
                update=":pageForm:pageTitle :pageForm:footer-main :popupDialogRegion :pageForm:MainPageContent"
                rendered="#{useAjaxPageNavigation}" 
                 >
                <f:param name="pageLink" value="#{pl.pageLink}" />
            </mytaglib:commandButton>

沿着这些思路。

所以第一个我们导航到这个单页应用程序并看到我们的菜单正在呈现,如果我们去调试命令按钮看起来非常漂亮和花哨。onclick 操作是所有设置都使用参数执行一个非常好的 ajax 请求......

   PrimeFaces.ab({
   s:"pageForm:mainMenuButtonsTouchBoxFramework:btn_controls:confirmSubmit",
   u:"pageForm:pageTitle pageForm:footer-main popupDialogRegion pageForm:MainPageContent",
   onco:function(xhr,status,args){boxFrameworkHelperJavascript.updateHeadPageTitle('Control / Events'); ;},
   pa:[{name:"pageLink",value:"/blalallaba/WHATEVENEPAGE.xhtml"},{name:"pageLinkDummyValue1",value:"dummtValue001"}]
   });
   return false;

这些命令按钮存在于数百页中,并且它们在 99% 的时间里都能完美运行。但是我们在具有多层模板的复杂页面上看到,JSF 复合组件有时会在重新渲染时炫耀伪影......

所以接下来是痛苦。

我们点击按钮。在服务器端

  FacesContext fc = FacesContext.getCurrentInstance();
        Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
        String pageLink = params.get("pageLink");

看起来不错。

但是后来……重新渲染灾难。

正在更新的菜单区域 :pageForm:footer-main 会返回选中的按钮。所有的 mnu 按钮都在那里。但是瞧,问题是我们这次的 onclick 事件很糟糕......

  PrimeFaces.ab({
           s:"pageForm:mainMenuButtonsTouchBoxFramework:btn_controls:confirmSubmit",
           u:"pageForm:pageTitle pageForm:footer-main popupDialogRegion pageForm:MainPageContent",
           onco:function(xhr,status,args){boxFrameworkHelperJavascript.updateHeadPageTitle('Control / Events'); ;}});return false;

看到两者在点击量上的区别了吗?参数消失了。

Composite:insert children 我们的复合组件在重新渲染区域时被忽略。

<p:commandButton id="confirmSubmit" 
            style="display:none;" 
            ajax="#{cc.attrs.ajax}"
            async="#{cc.attrs.async}"
            global="#{cc.attrs.global}"
            immediate="#{cc.attrs.immediate}"           
            oncomplete="#{func:object(cc.attrs.oncomplete)}"
            onerror="#{func:object(cc.attrs.onerror)}"
            onstart="#{func:object(cc.attrs.onstart)}"
            onsuccess="#{func:object(cc.attrs.onsuccess)}"
            partialSubmit="#{cc.attrs.partialSubmit}"
            process="#{func:object(cc.attrs.process)}"            
            update="#{func:object(cc.attrs.update)}"
            type="#{func:object(cc.attrs.type)}">
            <composite:insertChildren/>
         </p:commandButton>

解决问题?

是的……有一个。幸运的是一个体面的。

我们可以使用属性 actionListener 来代替 action。我们侥幸逃脱... 为什么因为我们不是依赖于对服务器发出正确的 ajax 请求并指定所有请求参数,而是从服务器端视图结构中获取参数。那是 :

public void navigateToPageAjaxActionListener(ActionEvent actionListenerEvent) {
    // (a) We use an action lister because we have problems with the composite component if we render it when we
    // navigate from page to page
    UIComponent component = actionListenerEvent.getComponent();
    UIParameter param = (UIParameter) component.getChildren().get(0);
    String pageLink = (String) param.getValue();

不漂亮,也不容易重现。有许多页面重新呈现此类按钮不会破坏参数。

这是一个已知的问题?是 primefaces 问题还是 JSF 版本问题。

JSF 2.2.8-35.jar。

标签: jsf-2.2

解决方案


推荐阅读