使用 JSF 和 AJAX 渲染隐藏元素
Render hidden elements using JSF and AJAX
我在使用带有 AJAX 的 JSF 来呈现 table 时遇到了一些问题,而无需在每次提交表单时重新加载整个页面。
当我第一次运行服务器时,我的数据库是空的,所以页面应该只显示一个添加书籍的表格。当用户提交表单时,应该呈现一个包含所有书籍的 fieldset
。我不想在数据库为空时显示此 fieldset
。
这是我的代码的一个简单版本(它只是一个小表格和一个 table 可以使用 AJAX 刷新):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:graphicImage library="img" name="caelum-logo.png"/>
<h:form>
<p>Book Title:</p>
<h:inputText id="title" value="#{livroBean.livro.titulo}" />
<h:commandButton value="Add book" action="#{livroBean.addFirstBook}">
<f:ajax execute="@form" render="title :addedBooksTable" />
</h:commandButton>
</h:form>
<div id="addedBooksTable">
<p:fieldset rendered="#{livroBean.numberOfBooks > 0}">
<h:dataTable value="#{livroBean.allBooks}" var="book">
<h:column>
<h:outputText value="#{book.titulo}" />
</h:column>
</h:dataTable>
</p:fieldset>
</div>
</h:body>
</html>
我想专注于这一部分:
<h:commandButton value="Add book" action="#{livroBean.addFirstBook}">
<f:ajax execute="@form" render="title :addedBooksTable" />
</h:commandButton>
字段集和其中的 table 应该在没有书添加到数据库时被隐藏,这就是我使用 <p:fieldset rendered="#{livroBean.numberOfBooks > 0}">
的原因。但是我希望在单击 commandButton
后渲染它,即使 inputText
.
处没有任何内容
这是我测试代码时发生的事情:
- 如果我像使用空数据库一样测试代码,当我单击
commandButton
,但字段集不是。我知道字段集有一个 rendered="#{livroBean.numberOfBooks > 0}"
而 inputText 没有,但是每次我单击命令按钮时都会调用方法 getNumberOfBooks
,这就是我不明白的原因...
- 如果我把
f:ajax
标签改成这样<f:ajax execute="@form" onevent="click" render="title :addedBooksTable" />
,问题就解决了,但是当我点击commandButton
.据我所知,AJAX的一个用途是我们不希望请求时屏幕闪烁。
为什么 fieldset
只在我使用 onevent="click"
时呈现?我应该认为闪烁是正常的吗?有没有更优雅的解决方案?
谢谢!
您不能 ajax-更新普通 HTML 元素。您只能 ajax-更新 JSF 组件。原因很简单,目标必须可由 UIViewRoot#findComponent()
解析,以便 JSF 可以在组件树中找到它并将更新后的 HTML 渲染到 Ajax 响应中。
替换
<div id="addedBooksTable">
来自
<h:panelGroup layout="block" id="addedBooksTable">
正常情况下,这应该会引发异常,如 How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar" 中所述,但他们在 Mojarra 2.2.5 中删除了此检查以支持 ajax-更新 [=13] 的特定迭代=] 和 <h:dataTable>
(这个缺失的检查将在稍后修复,因为这对像你这样的初学者确实没有帮助)。
至于为什么添加 onevent="click"
似乎有效,那是因为它导致 JavaScript 错误,进而导致整个 JavaScript/Ajax 事情崩溃,进而导致命令按钮回退到默认同步行为并重新加载整页(就好像您根本没有使用 <f:ajax>
一样)。您可能打算改用 event="click"
。 onevent
属性有不同的用途。另见 a.o。 Proccess onclick function after ajax call <f:ajax>.
我在使用带有 AJAX 的 JSF 来呈现 table 时遇到了一些问题,而无需在每次提交表单时重新加载整个页面。
当我第一次运行服务器时,我的数据库是空的,所以页面应该只显示一个添加书籍的表格。当用户提交表单时,应该呈现一个包含所有书籍的 fieldset
。我不想在数据库为空时显示此 fieldset
。
这是我的代码的一个简单版本(它只是一个小表格和一个 table 可以使用 AJAX 刷新):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:graphicImage library="img" name="caelum-logo.png"/>
<h:form>
<p>Book Title:</p>
<h:inputText id="title" value="#{livroBean.livro.titulo}" />
<h:commandButton value="Add book" action="#{livroBean.addFirstBook}">
<f:ajax execute="@form" render="title :addedBooksTable" />
</h:commandButton>
</h:form>
<div id="addedBooksTable">
<p:fieldset rendered="#{livroBean.numberOfBooks > 0}">
<h:dataTable value="#{livroBean.allBooks}" var="book">
<h:column>
<h:outputText value="#{book.titulo}" />
</h:column>
</h:dataTable>
</p:fieldset>
</div>
</h:body>
</html>
我想专注于这一部分:
<h:commandButton value="Add book" action="#{livroBean.addFirstBook}">
<f:ajax execute="@form" render="title :addedBooksTable" />
</h:commandButton>
字段集和其中的 table 应该在没有书添加到数据库时被隐藏,这就是我使用 <p:fieldset rendered="#{livroBean.numberOfBooks > 0}">
的原因。但是我希望在单击 commandButton
后渲染它,即使 inputText
.
这是我测试代码时发生的事情:
- 如果我像使用空数据库一样测试代码,当我单击
commandButton
,但字段集不是。我知道字段集有一个rendered="#{livroBean.numberOfBooks > 0}"
而 inputText 没有,但是每次我单击命令按钮时都会调用方法getNumberOfBooks
,这就是我不明白的原因... - 如果我把
f:ajax
标签改成这样<f:ajax execute="@form" onevent="click" render="title :addedBooksTable" />
,问题就解决了,但是当我点击commandButton
.据我所知,AJAX的一个用途是我们不希望请求时屏幕闪烁。
为什么 fieldset
只在我使用 onevent="click"
时呈现?我应该认为闪烁是正常的吗?有没有更优雅的解决方案?
谢谢!
您不能 ajax-更新普通 HTML 元素。您只能 ajax-更新 JSF 组件。原因很简单,目标必须可由 UIViewRoot#findComponent()
解析,以便 JSF 可以在组件树中找到它并将更新后的 HTML 渲染到 Ajax 响应中。
替换
<div id="addedBooksTable">
来自
<h:panelGroup layout="block" id="addedBooksTable">
正常情况下,这应该会引发异常,如 How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar" 中所述,但他们在 Mojarra 2.2.5 中删除了此检查以支持 ajax-更新 [=13] 的特定迭代=] 和 <h:dataTable>
(这个缺失的检查将在稍后修复,因为这对像你这样的初学者确实没有帮助)。
至于为什么添加 onevent="click"
似乎有效,那是因为它导致 JavaScript 错误,进而导致整个 JavaScript/Ajax 事情崩溃,进而导致命令按钮回退到默认同步行为并重新加载整页(就好像您根本没有使用 <f:ajax>
一样)。您可能打算改用 event="click"
。 onevent
属性有不同的用途。另见 a.o。 Proccess onclick function after ajax call <f:ajax>.