我遇到了'JSF bean生命周期行为'顺序的复杂问题。
我有两个不同范围的bean。第一个,我们称之为managerBean
是 session 范围bean。第二个,someBean
具有视图范围(someBean
确实有很多不同的bean)。每个页面加载ManagerBean
执行一次操作,而其他几个视图范围bean在其构造函数中使用此操作的结果。
一切正常,直到我开始从java bean获取xhtml文件中的表单ID。现在managerBean
的操作在创建 someBean
之后 ,并且仅在重新加载页面时才会获得预期结果(在刷新时,所以someBean
正在使用ManagerBean
工作的第一个结果。
这就是现在的样子:
<!-- mainTemplate is a main templete of the page which is rendered once
per page view (every other actions are taken via ajax). This is a place
of ManagerBean work after re rendering the page -->
<ui:composition template="/mainTemplate.xhtml">
<ui:define name="mainContent">
<h:form id="#{someBean.formID}">
some inputs
</h:form>
(...)
</ui:define>
</ui:composition>
所以当表单id是常量String时,一切都按照我想要的方式运行,现在却没有。看起来JSF必须首先计算ID并在此之后采取任何其他ID(包括ManagerBean
动作)。
我的问题是:有没有办法改变这种情况? 如果事情不明确,请询问。我试图简化问题,因为它有很多因素。也许我所有的想法都是错误的(我希望每页采取一些行动,然后采取一些行动)。
任何帮助都会很好!
答案 0 :(得分:1)
在视图构建期间评估JSF UI组件的id
(和binding
)属性。视图构建时间是将XHTML源代码转换为JSF UI组件树的那一刻。 JSF UI组件的所有其他属性(如value
)和所有事件(如preRenderView
)都在视图构建时间后评估/执行,通常在视图渲染时间内(当JSF UI时)组件树需要生成HTML输出)。这不是你可以通过转动设置左右来改变的东西。这就是JSF的工作方式。你无法渲染尚未构建的东西。你只能通过正确的方式编写代码来改变它。
我想不出任何真实场景为什么你需要让ID属性像这样动态。如果它在<c:forEach>
内,或者是动态组件生成的一部分,那么好吧,但这似乎只是一个静态形式。所以我首先建议忘记它,只是硬编码视图中的ID并依赖其他变量(可能是一个隐藏的输入字段?取决于具体的功能需求,在问题的任何地方都没有提到,也不能根据到目前为止发布的代码。)
如果您确实需要将其设置为动态,那么您需要将formID
属性从视图范围bean中拆分出来并将其移动到另一个独立的bean,可能是一个应用程序范围的bean。
id
属性与JSTL标记具有相同的生命周期