在延迟加载的AccordionPanel组件上,Object的属性更新为null

时间:2014-09-05 08:47:08

标签: jsf primefaces

我在我的网页上使用<p:accordionPanel dynamic="true">。提交页面时,未加载对象的属性将应用空值。我不想要这种行为,因为数据库和服务器端的值是正确的。为什么不在浏览器中显示它们导致在服务器端将它们归零。我认为不应该应用这些值,因为它们尚未被渲染。

我的xhtml(摘录):

<p:accordionPanel dynamic="true" value="#{controller.selectedObject.list}" var="listItem">
  <p:selectOneMenu value="#{list.market}" disabled="#{controller.selectedObject.isDisabled}">
    <f:selectItems value="#{marketSelectItems.selectItems}" />
  </p:selectOneMenu>
</p:accordionPanel>

假设controller.selectedObject.list包含两个BeanA条目,其中两个条目都有填充属性market
现在,当controller.selectedObject.isDisabled设置为true时,我的日志状态为:

10:21:12,565 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:25] UPDATE_MODEL_VALUES 4 before Phase
10:21:12,577 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:20] UPDATE_MODEL_VALUES 4 after Phase

一切正常,价值保持不变。

但是当controller.selectedObject.isDisabled设置为false时,我的日志会显示:

10:21:51,210 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:25] UPDATE_MODEL_VALUES 4 before Phase
10:21:51,228 INFO  [stdout] (default task-46) setMarket(de.mypackage.Market@2ed)
10:21:51,251 INFO  [stdout] (default task-46) setMarket(null)
10:21:51,265 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:20] UPDATE_MODEL_VALUES 4 after Phase

导致DB中存在错误值,导致信息丢失 当我打开第二个p:accordionPanel - 选项卡,导致加载数据时,一切正常,第二个BeanA - 对象被分配了正确的Market - 对象。

HTML不工作时:

<div class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" role="tablist" data-widget="widget_generalForm_instrumentDetailTabs_listingpanel">
  <h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-state-active ui-corner-top" role="tab" aria-expanded="true">
    headertext loremipsum
  </h3>
  <div id="generalForm:instrumentDetailTabs:listingpanel:0:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content" role="tabpanel" aria-hidden="false">
    <div>loaded CONTENT
    </div>
  </div>
  <h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-top" role="tab" aria-expanded="false">
     headertext loremipsum
  </h3>
  <div id="generalForm:instrumentDetailTabs:listingpanel:1:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content ui-helper-hidden" role="tabpanel" aria-hidden="true">
  </div>
  <input type="hidden" id="generalForm:instrumentDetailTabs:listingpanel_active" name="generalForm:instrumentDetailTabs:listingpanel_active" value="0">
</div>

点击第二个标签(或dynamic="false"

<div class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" role="tablist" data-widget="widget_generalForm_instrumentDetailTabs_listingpanel">
  <h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-state-active ui-corner-top" role="tab" aria-expanded="true">
    headertext loremipsum
  </h3>
  <div id="generalForm:instrumentDetailTabs:listingpanel:0:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content" role="tabpanel" aria-hidden="false">
    <div>loaded CONTENT
    </div>
  </div>
  <h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-top" role="tab" aria-expanded="false">
     headertext loremipsum
  </h3>
  <div id="generalForm:instrumentDetailTabs:listingpanel:1:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content ui-helper-hidden" role="tabpanel" aria-hidden="true">
    <div>loaded CONTENT OF TAB 2!!!
    </div>
  </div>
  <input type="hidden" id="generalForm:instrumentDetailTabs:listingpanel_active" name="generalForm:instrumentDetailTabs:listingpanel_active" value="0">
</div>

dynamic="false"上设置p:accordionPanel也会导致正确的行为,但我无法使用它。 accordionPanel包含许多组件,当controller.selectedObject.list包含大约15个项目时,页面大小大于1MB。

我该如何处理这个问题?为什么我的值会在没有渲染/加载的情况下更新?

版本信息:Primefaces 5.0,WildFly 8.1.0.Final

2 个答案:

答案 0 :(得分:1)

我找到了一种解决方法,将process="@this @(.myfakeclass)"添加到p:commandButton并使用 <p:outputPanel styleClass="myfakeclass">。这导致HTML <div>元素由不存在的类设置样式。在未加载的面板中,此类不会呈现,因此不会被处理。

我仍然认为这是Primefaces中的一个错误。

答案 1 :(得分:0)

这是primefaces中的已知错误。我在版本3.4.1中遇到过这种情况,由于其他错误,我无法从中升级。它可能已经修复,因为你不知道你正在使用哪个版本。

我使用了两种解决方法。对于小组件,我设置dynamic =&#34; false&#34;并在必要时隐藏html中的组件。对于较大的组件,我在setter中进行了一次空检查,并确保该值永远不能合法地设置为null。