【发布时间】:2026-02-12 06:05:01
【问题描述】:
我在请求范围内有一个操作。其方法之一的返回值被传递给自定义 facelet 标记。这个标签然后提取返回对象的几个属性并显示它们。问题是对于返回对象的属性的每次评估都会调用对 Action 进行方法调用的 EL 表达式。我会把相关的代码放在这里。
一些.xhtml
<ui:include src="someOther.xhtml">
<ui:param name="profileUri" value="#{param['relateToProfile']}"/>
<ui:param name="qualifier" value="#{param['qualifier']}"/>
<ui:param name="cellStyleClass" value="#{param['cellStyle']}"/>
</ui:include>
someOther.xhtml(方法一)注意 ProfileAction 在 @RequestScoped 中
<tenui:entityCard profileEntity="#{profileAction.getProfileMetadata(profileUri)}"
qualifier="#{qualifier}"
cellStyleClass="#{cellStyleClass}"/>
enityCard.xhtml(facelet 自定义标签)
<ui:fragment rendered="#{profileEntity.featured}">...
<tenui:gridCell id="#{profileEntity.profileId}#{qualifier}" ...
<tenui:metaunit ..content="#{profileEntity.getMeta('memberName')}"
href="/#{profileEntity.profileDisplayUri}"
hrefStyleClass="a-styled grid-cell-name"/>
.....
...several other EL expressions including #{profileEntity.xxx}
问题是 #{profileAction.getProfileMetadata(profileUri)} 正在为 entityCard.xhtml 中的每个属性评估调用然后,我想我会将方法调用的返回值保存在 ac:set var(approach 2 中,如下所述) 但它没有帮助。
someOther.xhtml(方法 2)
<c:set var="profileMetadata"
value="#{profileAction.getProfileMetadata(profileUri)}"/>
<tenui:entityCard profileEntity="#{profielMetadata}"
qualifier="#{qualifier}"
cellStyleClass="#{cellStyleClass}"/>
action 方法调用一个非常昂贵的存储过程,并且返回的对象有超过 20 个属性,这些属性在 entityCard.xhtml 中的 EL 中进行评估。
我还尝试了另一种方法,通过直接调用 action 方法来解析 ui:param 本身的值,但根本无济于事。问题依旧。
有人能指出我做错了什么吗?或者,如何避免对 profileAction.getProfileMetadata 调用的多次调用?
【问题讨论】:
-
您是否尝试将操作范围更改为
ViewScoped?它应该会有所帮助。 -
我可以尝试,但我不太明白它背后的基本原理。有一个获取实体卡的 Ajax 调用,我真的不希望 Bean 持续存在。此外,为什么将范围更改为 View 会对 EL 评估产生任何影响?
-
这只是建议,
ViewScoped只要用户在同一个视图中就可以存活。您写道有 ajax 调用。如果是这样,则每次 ajax 调用都会重新创建范围。也许这就是为什么你的方法每次都被调用的原因。 -
对不起,我应该解释得更好。有一个单一的 ajax POST 调用(由 Firebug 控制台正式验证),它加载 some.xhtml,并传递 3 个参数。这反过来又调用 someOther.xhtml,它使用
Requestscopedbean 方法的返回值初始化自定义标记。然后,自定义标记评估该返回对象的几个属性。但相反,它似乎正在评估方法调用本身,以获取它需要在返回的对象上获取的每个属性! -
代替
<c:set>,你能试试<ui:param>吗?