我有一个组件来显示一个条目。这个组件可以在同一个页面中出现多次,因此只需要一个实体,将它传递给组件的支持 bean,所有的魔法都会发生。
组件的外观会受到各种参数的影响。
现在,一个要求是,无论我有 1 个还是 10 个这些组件,都应该可以使用深度链接恢复“相同”的视图状态。
假设我的组件如下所示:
<composite:interface componentType="itemView" >
<composite:attribute name="item" required="true" shortDescription="The item to display."/>
<composite:attribute name="urlPrefix" required="true" />
</composite:interface>
<composite:implementation>
<f:event type="preRenderComponent" listener="#{cc.init}" />
....
</composite:implementation>
它有一个对应的backing Bean,我可以访问。(省略这个,因为它不是必需的)
现在,这些组件被嵌入到一个页面中,如下所示:
<f:metadata>
<f:viewParam name="itemType"
value="#{listController.itemType}"></f:viewParam>
</f:metadata>
<ui:define name="content">
<!-- multiple occurences, ui repeat over list of items -->
<my:itemView item="#{currentItem}" urlPrefix="#{listController.nextLetter}">
如前所述,每个项目的状态都可能受到影响,并且更改后的状态必须可以通过深度链接访问。所以,我的想法是,<h:link>
在组件内部使用,为每个属性添加前缀并使用includeViewParams="true"
,这样每个(非默认)状态都是 url 的一部分。
<composite:interface componentType="itemView" >
<composite:attribute name="item" required="true" shortDescription="The item to display."/>
<composite:attribute name="urlPrefix" required="true" />
</composite:interface>
<composite:implementation>
<f:event type="preRenderComponent" listener="#{cc.init}" />
<h:link includeViewParams="true">
<f:param name="#{cc.attrs.urlPrefix}size" value="#{cc.largerSize}" />
larger
</h:link>
....
</composite:implementation>
就像“更大”的链接一样,最多有 10 个链接,提供不同的选项。
问题: include-view-params确实包含来自同一组件及其父级 (itemType) 的所有视图参数,但不包含来自其他组件的所有视图参数。所以,基本上改变“一个”组件的样式,会丢弃另一个组件的参数。
预期:网址已经看起来像?itemType=something&asize=5&abackground=green
单击b组件上的“更大”链接会给我:?itemType=something&asize=5&abackground=green&bsize=5
发生了什么:单击链接后,网址如下所示:?itemType=something&bsize=5
因此“a”的属性被删除。
我注意到,如果我<f:metadata>
在列表页面上扩展对象时使用<f:viewParam name="asize" />
aSize 参数之类的东西,当从“b”中单击某些东西时,将被保留 - 但当然,如果我需要列出所有类似的参数,我不需要组件,因为我无法预测项目的数量。
所以,我试图在组件内添加它(如 f:event):<f:viewParam name="#{cc.urlPrefix}size" />
- 但这不起作用。
对此有任何想法(或替代解决方案?注意:将视图状态保存在数据库中,并且简单地使用“单个”id 来引用该状态基本上是不好的,因为这会导致大量数据污染。视图状态需要保持短暂,但可恢复:0))