微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JSF 命令按钮 F 参数在按钮的 AJAX 重新渲染时丢失 - 解决方法 ActionListener

如何解决JSF 命令按钮 F 参数在按钮的 AJAX 重新渲染时丢失 - 解决方法 ActionListener

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

我面临的问题听起来很像: https://forum.primefaces.org/viewtopic.php?t=27870

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

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

composite:implementation

基于素面

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",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。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。