使用 AJAX (JSF+richfaces) 重新渲染显示/隐藏技巧仅适用于 a4j:repeat 中的第一条记录

发布于 2024-09-24 04:03:27 字数 2713 浏览 4 评论 0原文

一段时间以来,我一直致力于一个基于 JAVA 的 Web 项目,并且发现这个网站在很多情况下都非常有帮助。
所以,“我现在遇到了一些问题 - 如果您能提供帮助,我将不胜感激!”

好的,事情是这样的 -
我正在尝试呈现消息列表,每条消息都包含消息标题和消息正文。我正在研究的技巧是,只要标题(a4j:commandLink)没有被单击,消息正文就应该被隐藏。一旦点击标题 - 正文就会显示出来。一旦再次点击 - 隐藏。等等。
这是我在 JSF 方面所做的事情(为了简单起见,省略了一些部分):

<a4j:repeat var="msg" value="#{ForumRenderJSF.messages}">
    <a4j:region id="msgAjaxRegion" renderRegionOnly="true">
    <a4j:outputPanel id="msgPanel" ajaxRendered="true">
    <rich:panel style="width: 100%; border: 0">
    <a4j:form id="msgForm">

        <!--
         The message's title.
         Each click results in either the revealing or hiding of the message's body.
         -->

        <a4j:commandLink value="#{msg.title}" action="#{ForumRenderAssistJSF.reevaluateRender}"/>
        <h:outputText value="  By: <i>#{msg.userNick}</i>,   #{msg.timestamp}" escape="false"/>

        <!--
         The message's body.
         -->

        <!-- A (textual) flag, indicating whether the body should be rendered. -->
        <h:inputText id="renderBodyFlag"/>

        <br/>
        <!-- The body. -->
        <a4j:outputPanel rendered="#{rich:findComponent('renderBodyFlag').value == true}">
            <h:outputText value="#{msg.body}"/>
        </a4j:outputPanel>

    </a4j:form>
    </rich:panel>
    </a4j:outputPanel> <!-- msgPanel -->
    </a4j:region>

</a4j:repeat>

注意以下的用法:
1. 一个虚拟的“renderFlag”字段(最终应该隐藏),该值表示是否应该渲染主体。
2. 用于渲染辅助的支持 bean (ForumRenderAssistJSF);它的目标是将正确的 renderFlag 值从“true”翻转为“false”,反之亦然。
3. 一个a4j:region,用于在触发ForumRenderAssistJSF.reevaluateRender() 请求时隔离每条消息——以便bean 可以找到正确的“renderFlag”字段。

至于豆子:

public class ForumRenderAssistJSF {
public void reevaluateRender()
    {
        FacesContext    context = FacesContext.getCurrentInstance();
        UIViewRoot      root = context.getViewRoot();
        UIComponent     renderFlagComp = (new UIComponentLookup()).lookup(root, compLookup); // My recursive search
        String          renderFlagVal = (String) ((HtmlInputText)renderFlagComp).getValue();

        if (!renderFlagVal.equals("true"))
        {
            ((HtmlInputText)renderFlagComp).setValue("true");
        }
        else
        {
            ((HtmlInputText)renderFlagComp).setValue("false");
        }
    }
}

问题是:
这个技巧确实有效——但仅适用于列表中的第一条消息! 对于其余的,我看到服务器可以到达正确的 renderFlag 输入文本组件(通过在客户端插入值进行测试),但由于某种原因 - 客户端在 AJAX 回复时总是将其呈现为空白(无内容)!

我尝试深入研究 richfaces 教程和手册,对我来说,一切似乎都应该如此。所以,我有点迷失在这里,正如我所说 - 非常感谢您的帮助!

谢谢!

For a while now, I've been working on a JAVA-based web project, and have found this website to be very helpful on numerous occasions.
So, 'got some problems of my own now - and would appreciate if you help out!

Ok, so Here's the thing -
I'm trying to render a list of messages, each of which consists of a message title and a message body. The trick I'm working on is that the message body, for as long as the title (which is an a4j:commandLink) hasn't been clicked-on, should be hidden. And once the title's clicked - the body should be displayed. And once its clicked again - hide. And so forth.
Here's what I did at the JSF side (some parts have been omitted for simplicity):

<a4j:repeat var="msg" value="#{ForumRenderJSF.messages}">
    <a4j:region id="msgAjaxRegion" renderRegionOnly="true">
    <a4j:outputPanel id="msgPanel" ajaxRendered="true">
    <rich:panel style="width: 100%; border: 0">
    <a4j:form id="msgForm">

        <!--
         The message's title.
         Each click results in either the revealing or hiding of the message's body.
         -->

        <a4j:commandLink value="#{msg.title}" action="#{ForumRenderAssistJSF.reevaluateRender}"/>
        <h:outputText value="  By: <i>#{msg.userNick}</i>,   #{msg.timestamp}" escape="false"/>

        <!--
         The message's body.
         -->

        <!-- A (textual) flag, indicating whether the body should be rendered. -->
        <h:inputText id="renderBodyFlag"/>

        <br/>
        <!-- The body. -->
        <a4j:outputPanel rendered="#{rich:findComponent('renderBodyFlag').value == true}">
            <h:outputText value="#{msg.body}"/>
        </a4j:outputPanel>

    </a4j:form>
    </rich:panel>
    </a4j:outputPanel> <!-- msgPanel -->
    </a4j:region>

</a4j:repeat>

Note the usage of:
1. A dummy "renderFlag" field (should be hidden, eventually), which value denotes whether the body should be rendered.
2. A backing bean for rendering assistance (ForumRenderAssistJSF); It goal is to flip the proper renderFlag's value from "true" to "false", and vice-versa.
3. An a4j:region to isolate each message when firing the request for ForumRenderAssistJSF.reevaluateRender() -- so that the bean can find the right "renderFlag" field.

As for the bean:

public class ForumRenderAssistJSF {
public void reevaluateRender()
    {
        FacesContext    context = FacesContext.getCurrentInstance();
        UIViewRoot      root = context.getViewRoot();
        UIComponent     renderFlagComp = (new UIComponentLookup()).lookup(root, compLookup); // My recursive search
        String          renderFlagVal = (String) ((HtmlInputText)renderFlagComp).getValue();

        if (!renderFlagVal.equals("true"))
        {
            ((HtmlInputText)renderFlagComp).setValue("true");
        }
        else
        {
            ((HtmlInputText)renderFlagComp).setValue("false");
        }
    }
}

AND THE PROBLEM IS:
The trick actually works -- but only for the first message in the list!
For the rest of them, I see that the server can reach the right renderFlag input-text component (tested by inserting values at the client), but for some reason - the client always renders it blank (no content) upon AJAX reply!

I tried digging deep inside richfaces tutorials and manuals, and to me it seems like everything is as it should be. So, I'm kind'a lost here, and as I said - would deeply appreciate your help in regards!

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

错々过的事 2024-10-01 04:03:27

您是否尝试过使用 rich:simpleTogglePanel ?它似乎提供了您需要的所有功能。

Have you tried using a rich:simpleTogglePanel? It seems to provide all the functionality you need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文