假设我有一小段代码:
<h:panelGroup id="panel1" rendered="falseByDefault">
<h:selectBooleanCheckbox value="#{bean.booleanProperty}">
<f:ajax event="click" render="alwaysrendered">
</h:selectBooleanCheckbox>
</h:panelGroup>
<h:panelGroup id="alwaysrendered">
<h:panelGroup id="panel2" rendered="#{!bean.booleanProperty}">
<p>Some stuff here</p>
</h:panelGroup>
</h:panelGroup>
在我按下另一个组件之前,不会渲染panel1。 booleanProperty默认为true,直到我按下booleanCheckBox,因此panel2应该出现在那一刻,因为ajax请求重新呈现alwaysrendered。
它不起作用。我认为因为“f:ajax”标记位于页面加载时未呈现的组件内。
您如何看待这个?你还知道其他任何方法吗?
总结:我想渲染一个组件,其中的标签位于默认情况下未呈现的面板内。
谢谢!
答案 0 :(得分:1)
它不起作用。我认为因为标签位于页面加载时未呈现的组件内。
这正是问题所在。 JSF ajax通过用新版本替换浏览器的DOM-Tree中的元素来更新工作。但是如果没有这样的元素带有你刚重新渲染的ID,因为它之前没有呈现过,那么浏览器不知道放置该更新元素的位置并忽略它。
尝试这样的事情:
<h:panelGroup id="panel2" >
<h:panelGroup rendered="#{!bean.booleanProperty}">
<p>Some stuff here</p>
</h:panelGroup>
</h:panelGroup>
您还需要将bean设置为至少@ViewScoped
。这是因为它的工作原理如下:
由于“rendered="falseByDefault"
”,最初您的第一个面板不可见。然后单击其他内容,该条件变为true
,使您的面板可见,但仅针对该一个请求+响应。现在,您单击该可见面板中的复选框,并希望将#{bean.booleanProperty}
设置为另一个值以显示panel2。请求将被发送,但JSF会对该请求执行一些有效性检查。它还会检查您刚刚单击的复选框,可以点击(这意味着它是可见的)。但是因为该复选框周围的面板不再可见(仅在一个请求中可见),JSF决定此请求无效并且不按您希望的方式处理它。这就是为什么你的复选框的布尔值永远不会改变,你的panel2将不可见。
根据经验:永远不要将@RequestScoped
与Ajax请求一起使用。
答案 1 :(得分:0)
您需要在panelGroup“pane2”周围放置一个带id的包装标签,然后在ajax渲染属性中引用该标签。这是必需的,因为javascript尝试按id更新组件。但是当它没有被渲染时因此没有被发现也不会发生更新。