【发布时间】:2026-01-04 21:40:02
【问题描述】:
有没有办法在运行时而不是设计时指定 EL 中使用的托管 bean?例如。
actionListener="#{myBean.method}" 使得 myBean 部分可以具有不同的值,具体取决于调用代码的 JSF 页面(前提是使用的任何对象而不是 myBean 都派生自实现“方法”的公共父级)。
【问题讨论】:
有没有办法在运行时而不是设计时指定 EL 中使用的托管 bean?例如。
actionListener="#{myBean.method}" 使得 myBean 部分可以具有不同的值,具体取决于调用代码的 JSF 页面(前提是使用的任何对象而不是 myBean 都派生自实现“方法”的公共父级)。
【问题讨论】:
如果您事先知道 bean 范围并且事先已经创建了 bean,那么可以,可以使用以下语法:
actionListener="#{requestScope[beanName].method}"
其中#{requestScope} 代表请求范围映射(相同的映射可用于视图、会话和应用程序范围),#{beanName} 代表保存托管 bean 名称的变量。
如果您事先不知道 bean 范围和/或没有事先创建 bean,那么您需要创建一个执行 Application#evaluateExpressionGet() 的实用 EL 函数,以便可以使用它如下:
actionListener="#{util:getBean(beanName).method}"
【讨论】:
#{viewScope[beanName].method}。您也许可以使用视图 ID 作为 bean 名称。您可以使用#{view.viewId} 获取视图ID。您可能只需要从中拆分路径 / 和父文件夹。您可以为此使用 JSTL 函数。
#{beanName} 来完成)。我更新了答案。您最好的选择似乎确实使用了一些 EL 实用功能(或者在使用 EL 2.2 时,甚至是应用程序范围托管 bean 的一些辅助方法)。您可以在此答案中找到如何创建自定义 EL 函数:*.com/questions/7079978/…
如果您的问题涉及为具有公共元素的多个子类生成一组页面,您也可以使用页面组合来实现此目的。
例如,如果 Resident 和 Nonresident 是 Person 子类的托管 bean:
例如。在'non-resident.xhtml'中
<ui:define name="body">
<ui:param name="Controller" value="#{NonResident}"/>
<ui:include src="anyone.xhtml"/>
</ui:define>
在“resident.xhtml”中
<ui:define name="body">
<ui:param name="Controller" value="#{Resident}"/>
<ui:include src="anyone.xhtml"/>
</ui:define>
然后'anyone.xhtml'可以使用'Controller'作为bean名称来定义公共元素。
这种方法还可以让您消除重复的页面定义。
【讨论】: