我有一个 selectonlistbox,我想在每次进行/更改选择框选择时重新加载一个面板网格。我尝试只使用 jsf 1.2。
我知道使用 a4j 或 faces 2 可以轻松完成,但如果有人知道在 jsf 1.2 中实现这一目标的任何好方法,我将不胜感激。
一个简单的例子也会有很大帮助。
谢谢
您基本上需要创建一个自定义 Ajax 感知ViewHandler
以及一个自定义 XMLResponseWriter
和自定义标记,它们生成所需的 JavaScript 代码来执行XMLHttpRequest
工作和 HTML DOM 操作。这也是大多数第 3 方 JSF 1.x 组件库所做的。它们都是开源的,所以你可以看看它的源代码,通过例子来学习他们是如何做到的。毕竟这是一个初学者,但不是一项简单的工作,因为它需要深入了解 HTTP、HTML DOM、JavaScript 和 XMLHttpRequest 的工作原理。很快就会犯一个小错误,初学者需要很长时间才能找到并真正理解它。
您最好的选择实际上是为 JSF 1.2 采用支持 ajax 的组件库(例如,包含 Ajax4jsf的RichFaces 3.x ),或者只是迁移到 JSF 2.0(JSF 1.2 已经超过 6 年了,而 JSF 2.0 是在将近 3 年前引入的已经;JSF 1.x 基本上是历史)。
然而,这个特殊的功能需求也可以在没有 ajax 的情况下完成,尽管有点笨拙,当然如果表单验证起作用的话。这是一个基本的启动示例,只需指示 JavaScript 在下拉列表更改时提交父表单:
<h:form>
<h:selectOneMenu value="#{bean.selected}" onchange="this.form.submit()">
<f:selectItem itemValue="one" />
<f:selectItem itemValue="two" />
<f:selectItem itemValue="three" />
</h:selectOneMenu>
<h:panelGroup rendered="#{bean.selected == 'one'}">
One was selected.
</h:panelGroup>
<h:panelGroup rendered="#{bean.selected == 'two'}">
Two was selected.
</h:panelGroup>
<h:panelGroup rendered="#{bean.selected == 'three'}">
Trree was selected.
</h:panelGroup>
</h:form>
这将在下拉列表更改时同步提交整个表单,就像您按下提交按钮一样。但是,如前所述,如果您在同一个表单的其他地方执行验证,则必须引入相当多的技巧immediate="true"
并valueChangeListener
阻止对所有其他表单元素的验证。有关一些详细示例,另请参阅填充子菜单。
一个完全不同的替代方案是仅将所有内容呈现到 HTML 响应并使用 CSS 将其隐藏display:none
,然后在属性element.style.display
中引用的某些 JS 函数中使用 JavaScript 切换显示。onchange
我认为更好的选择是迁移到 JSF 2。如果您想使用 JSF 1.2 进行此操作,请使用一些 JS 库(例如 JQuery 或原型)并在事件上调用您的 JS 函数并使用带有面板网格的模板页面的 URL 调用 AJAX 更新程序和逻辑(例如:/mypanaelGrid.jsf)。