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