【问题标题】:JSF: ui:include and the (broken) view scopeJSF:ui:include 和(损坏的)视图范围
【发布时间】:2012-09-06 22:22:06
【问题描述】:

我有一个 JSF 页面,其中包含一些常见元素,然后是 4 个根据各种用户操作动态加载和包含的部分。我有封装各种包含功能的 bean,结构是这样的:

mainview.xhtml 
     --backed by--> mainViewBean (request scope) 
       --with managed property--> mainViewView (view scope)

include1.xhtml
     --backed by--> include1Bean (request scope)
       --with managed property--> mainViewBean

include2.xhtml
     --backed by--> include2Bean (request scope)
       --with managed property--> mainViewBean

include3.xhtml
     --backed by (and with component bindings to)--> include3Bean (request scope)
       --with managed property--> mainViewBean

include4.xhtml
     --backed by--> mainViewBean

在主视图页面上,每个包含都通过一系列条件渲染的 h:panelGroups 包含在 BalusC 在这些问题中的描述中:

https://stackoverflow.com/a/9897016/945403

https://stackoverflow.com/a/7113961/945403

视图范围 bean 包含一些关于用户活动当前状态、他们当前正在查看的项目等的各种视图信息。

每个包含的视图都通过 ajax 和非 ajax 帖子执行各种任务。我的问题是某些面板中的某些操作似乎会导致视图范围被破坏,并且似乎没有押韵或理由。对于下面概述的复杂工作流程,我提前道歉,但我会尽量做到清楚。

如果我在 include3.xhtml 中执行 ajax 操作,它们只会在 include 中呈现组件,我可以整天这样做,并且视图范围仍然存在。如果我执行非 ajax 帖子,刷新将更新(并可能添加以前未渲染的)include4.xhtml。然后我可以随后在任何其他包含中执行操作。

如果我在 include1.xhtml 中执行一个 ajax 操作,它只调用它自己的支持 bean 中的方法,并且只更新它自己的组件,那么视图范围仍然存在。如果我执行调用 include3Bean 中的方法并更新包含 include2.xhtml 和 include3.xhtml 的 div 的 ajax 操作,则视图范围仍然存在,只要我继续在 include1.xhtml 中执行操作,视图范围就会保留。一旦我尝试在另一个包含中执行另一个操作,视图范围就会被破坏。

在这一点上,我认为问题一定在于我正在更新不同的包含,而不是从中调用操作。但这似乎不是我现在要解释的问题(或至少是唯一的问题)。

include2.xhtml 有一个 ajax 动作,当它被触发时,它会调用 mainViewBacking 中的一个方法并更新包含 include2.xhtml 和 include3.xhtml 的 div。如果我继续执行此操作,或在 include2.xhtml 中执行任何其他操作(包括非 ajax 操作),一切都会按预期工作,并且视图范围仍然存在。但是,如果我随后在 include3.xhtml 中执行操作,则视图范围被破坏。奇怪的是我可以在 include1.xhtml 中执行操作,并且只要我愿意,他们就可以继续访问视图范围,但是如果我尝试返回并执行操作在 include2.xhtml 或 include3.xhtml 中,视图范围又丢失了。

我在这一点上有点卡住,我什至不确定如何找出问题所在。我假设一些关于刷新(以及删除或添加)包含的内容会导致视图范围丢失,但从之前链接的问题来看,这似乎不是问题,因为 ui 的实际 src 值:includes 不是动态生成的。而且我确实关闭了 mainview.xhtml 的部分状态保存。

这些动态显示的 ui:includes 是否存在破坏视图范围的问题?

【问题讨论】:

  • 2 个问题:您使用的是什么版本的 mojarra?您是否将任何输入组件绑定到支持 viewscoped bean?有关组件的绑定,请参阅mojarra bug。还要确保您没有执行重定向到也引用相同视图范围 bean 的页面。
  • @kolossus 使用 Morjarra 2.1.3。 include3.xhtml 有一些组件绑定到请求范围的 include3Bean (通过托管属性链接可以访问视图范围的 bean)但我的理解是,只要绑定不在实际的视图范围 bean 中,并且我关闭此视图的 PATIAL_STATE_SAVING 应该没问题。此外,不会发生重定向,所有操作都是无效操作。

标签: ajax jsf-2 mojarra view-scope uiinclude


【解决方案1】:

编辑 2014-02-28:

在查看最新的 omnifaces 展示时,我注意到 BalusC 已经实现了一个脚本,它应该可以解决同样的问题,并且可能以比我下面的代码更好的方式来解决这个问题。

http://showcase.omnifaces.org/scripts/FixViewState

原答案:

事实证明这是 BalusC 在此处描述的 JSF 中的一个错误:http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm

不幸的是,由于某种原因,他的解决方案对我来说并不能始终如一地工作。结果,我编写了自己的(稍微烦人的)工作,如果他们需要,我会在这里提供给其他人。

我在 mainview.xhtml 页面中添加了以下 javascript:

var lastForm = null;

        function getViewStateFromLastForm(callingElement){

            var currentForm = $(callingElement).closest("form");
            var formId = currentForm.attr("id");

            if(lastForm != null ){
                var viewState = $("#" + lastForm).children("[name='javax.faces.ViewState']").val();
                currentForm.children("[name='javax.faces.ViewState']").remove();

                $('<input/>').attr({
                    type: 'hidden',
                    id: 'javax.faces.ViewState',
                    name: 'javax.faces.ViewState',
                    autocomplete: 'off',
                    value: viewState
                }).appendTo(currentForm);
            }
            lastForm = formId;

        }

然后提交给服务器的各个包含页面上的每个按钮在其 onclick 属性中都有一个调用 getViewStateFromLastForm(this);

【讨论】:

    猜你喜欢
    • 2013-03-20
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 2021-03-24
    • 1970-01-01
    相关资源
    最近更新 更多