如何解决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 举报,一经查实,本站将立刻删除。