使用JSF和AJAX渲染隐藏元素

4
我在使用JSF和AJAX渲染表格时遇到了一些问题,每次提交表单时不想重新加载整个页面。当我第一次运行服务器时,我的数据库是空的,所以页面应该只显示一个添加书籍的表单。当用户提交表单时,应该呈现带有所有书籍的字段集。但是我不希望在数据库为空时显示这个字段集。这是我的代码简化版(它只是一个小表单和一个要使用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>

当数据库中没有书籍时,<p:fieldset rendered="#{livroBean.numberOfBooks > 0}"> 会隐藏 fieldset 和其中的表格。但是我想要在点击 commandButton 后呈现它,即使 inputText 中没有内容。

以下是测试代码时发生的情况:

  • 如果我在空数据库中测试代码,当我点击commandButton时,inputText会被刷新(它会“擦除”之前输入的内容),但是fieldset不会。我知道fieldset有一个rendered="#{livroBean.numberOfBooks > 0}"inputText没有,但是每次我点击commandButton时都会调用getNumberOfBooks方法,这就是我不明白的原因...
  • 如果我改变f:ajax标签,使其变成这样<f:ajax execute="@form" onevent="click" render="title :addedBooksTable" />,它可以解决问题,但是当我点击commandButton时,屏幕会闪烁一段时间。据我所知,AJAX的一个用途是在发出请求时不希望屏幕闪烁。

为什么只有使用onevent="click"时才渲染fieldset?我应该认为闪烁是正常的吗?有更优雅的解决方案吗?

谢谢!

1个回答

4
你无法通过AJAX更新一个纯HTML元素,只能更新JSF组件。原因很简单,因为目标必须可以被UIViewRoot#findComponent()解析,这样JSF就可以在组件树中找到它,并将更新后的HTML呈现到AJAX响应中。
替换:
<div id="addedBooksTable">

by

<h:panelGroup layout="block" id="addedBooksTable">

通常情况下,这应该会抛出异常,如如何找到用于ajax更新/渲染的组件的客户端ID?无法从“bar”中引用表达式“foo”的组件所述。但是,在Mojarra 2.2.5中,他们删除了此检查,以支持ajax更新特定的<ui:repeat><h:dataTable>迭代(稍后将修复此缺失的检查,因为对像您这样的初学者确实没有帮助)。
至于为什么添加onevent =“click”似乎有效,那是因为它导致JavaScript错误,进而导致整个JavaScript / Ajax事物崩溃,进而导致命令按钮回退到默认同步行为并重新加载整个页面(就好像您根本没有使用<f:ajax>)。您可能想使用event =“click”onevent 属性具有不同的用途。还可以参见在ajax调用<f:ajax>之后处理onclick函数

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接