【发布时间】:2015-02-14 19:38:33
【问题描述】:
我经常遇到以下问题。我有一个 JSF 应用程序和一个 facelet,我可以在其中编写 EL 表达式,如下所示:
<h:outputText value="#{myBean.foo}">
只要myBean作为一个变量有足够长的寿命,在任何给定时间评估myBean.foo都没有问题,但是如果myBean是一个在短时间内引用某个bean的变量时间,当 myBean.foo 被评估时可能为时已晚,因此 JSF 抱怨 myBean 解析为 null。这是众所周知的事情,但问题是我不清楚在不同情况下会发生什么。
具体例子 n. 1:如果您使用 PrimeFaces OrderList 尝试以下操作:
<p:orderList value="#{bean.myValue}" var="item">
<p:column>
<p:commandLink action="#{bean.doSomething(item)}" />
</p:column>
</p:orderList>`
这是行不通的,因为当调用doSomething 时,不再定义item 变量(尽管它引用的对象仍然存在),因此它被解析为null。这是known issue。但是,例如,相同的模式适用于 <p:dataTable>。无论如何,我现在对这个具体问题不感兴趣,我只是想解释一下我的疑问。
具体例子 n. 2:我编写了一个带有支持 bean 的复合组件。支持 bean 扩展 UINamingContainer 并使用其 StateHelper 来保留模型对象。这个复合允许写子标签,我想写这样的东西:
<myns:myCc var="myVar">
<h:inputText value="#{myVar.foo}" />
</myns>
对于“myVar”,我想为模型对象命名。为了完成这项工作,我尝试将模型对象存储在 encodeChildren 方法开头的请求映射中,然后将其删除:这适用于渲染,但如果我随后使用 commandButton 操作处理输入,则它不起作用因为当动作被执行时,它说myVar 无法解析:换句话说,它试图解析整个表达式为时已晚。然后我尝试将模型对象“永久”保存在视图范围图中,但它也不起作用。但是,如果我将其更改为:
(假设 modelObject 是存储我的模型对象的支持 bean 中的属性字段)
有用。所以,这不是我的模型的问题,而是我尝试使模型对象可用于子标签的 EL 表达式的方式。
具体例子 n. 3:我经常使用<ui:param>标签来给bean一个更短的名字并简化模板。例如:
<ui:param name="bean" value="#{longNamedAndPageSpecificBean}" />
因此,在页面的其余部分我可以只使用#{bean.foo} 而不是#{longNamedAndPageSpecificBean.foo}。即使对于传递给命令按钮的操作,这也能正常工作。但是,如果我将#{bean.myActionMethod} 之类的方法表达式传递给使用method-signature 声明的复合组件属性,则当实际调用此方法表达式时,我会收到bean 解析为null 的错误...在一种情况下工作(使用 commandButton 操作)而不在另一种情况下工作(使用复合组件使用的操作)对我来说是一个很大的困惑。
如果有人能帮助我更好地理解 JSF 方面,并通过上述具体示例提出更好的方法/解决方法,我将不胜感激。
【问题讨论】:
标签: jsf el composite-component