在从此模板中签出OmniFaces展示应用程序代码时,遇到了p:selectOneMenu中使用的以下条件
disabled="#{facesContext.postback and not facesContext.renderResponse}"从应用程序的使用来看,selectOneMenu似乎从未被禁用过,那么这段代码到底是做什么的呢?
我知道,当页面是由JSF生成的POST请求(命令but /命令链接等)生成时,facesContext.postback是true,但是在视图中进行评估时,facesContext.renderResponse的预期状态是什么呢?
UPDATE: oops,刚才我看到了这样的评论:除了呈现响应之外,它们在其他阶段被禁用,因为它们抱怨即使没有表单,也无法设置模型值。
因此,我猜想这个条件在Faces生命周期中会被多次评估,并且组件被禁用,直到达到最后一个状态(renderResponse),当facesContext.renderResponse计算为true时,整个表达式计算为false,然后启用该组件。你说的对吗?
发布于 2012-12-28 12:30:39
这些<p:selectOneMenu>组件实际上被滥用来拥有一个包含最少代码的漂亮的<div><ul><li>下拉菜单;)它们的值表示当前的菜单项和页面,这些菜单组和页面都是设计为只读的(它们没有setter方法)。导航由JavaScript window.location进行,它在更改事件期间处理。他们不是任何形式的一部分,也不参与任何形式的提交。
理论上,disabled属性不是强制性的,但是当同一页面中其他地方的非ajax JSF表单同步提交时,PrimeFaces SelectOneMenuRenderer仍然会尝试将其作为一个整体进行decode(),即使它根本不包含在任何形式中。当要更新模型值时,它最终会导致以下异常,因为该值没有setter:
javax.el.PropertyNotWritableException: /WEB-INF/templates/showcase.xhtml @28,80 value="#{parent.children[0].viewId}": The class 'org.omnifaces.showcase.Page' does not have a writable property 'viewId'.
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at org.primefaces.component.panel.Panel.processUpdates(Panel.java:304)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)当disabled属性在回发期间计算true时,SelectOneMenuRenderer将在应用请求值阶段跳过decode(),从而跳过模型值的更新。但是,如果它在true期间也计算渲染响应阶段,那么它就变得不可选择(因此无法使用)。因此,它不应该在呈现响应阶段评估true。表达式
disabled="#{facesContext.postback and not facesContext.renderResponse}"做到这一点。总之,这基本上是SelectOneMenuRenderer奇怪行为的一种解决方法(我还没有真正研究其根本原因)。
要亲自测试它,请拉出项目,删除disabled属性,并在例如<o:onloadScript>展示页面中调用同步提交。
发布于 2012-12-28 11:53:27
这将计算为吸气状态,用于读取是否已调用renderResponse()。该方法用于指示JSF生命周期跳过后续阶段并直接发出响应(例如,在验证失败的情况下)。
https://stackoverflow.com/questions/14068891
复制相似问题