You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Primefaces graphicImage Ajax删除后不刷新问题求助

这个问题我之前也碰到过,核心原因是你用了JSTL的<c:forEach>来渲染图片列表,而不是JSF原生的<ui:repeat>组件,导致Ajax更新时页面无法重新生成最新的图片组件。下面给你详细的解决方案:

问题根源

<c:forEach>是JSTL标签,它在视图构建阶段(页面首次加载时)就执行完毕,生成对应的JSF组件树。当你通过Ajax删除图片后,虽然后台Bean里的hm2已经更新,但JSF在重新渲染时只会复用之前构建好的组件树,不会重新执行<c:forEach>,所以页面上还是显示原来的图片列表。

而<ui:repeat>是JSF的迭代组件,它在视图渲染阶段执行,每次渲染(包括Ajax更新后的渲染)都会遍历当前的hm2集合,生成最新的组件,完美适配Ajax场景。

解决方案步骤

  1. 替换<c:forEach>为<ui:repeat>
    修改你的JSF页面代码,把遍历图片列表的<c:forEach>换成<ui:repeat>,注意要遍历hm2的entrySet()(因为hm2是LinkedHashMap,<ui:repeat>需要明确遍历集合):
<h:form id="tempForm" enctype="multipart/form-data">
    <h:panelGroup id="graphicImageCustomerPicturePanel">
        <div class="card">
            <p:panelGrid columns="2" columnClasses="ui-grid-col-6,ui-grid-col-6" layout="grid"
                         styleClass="ui-panelgrid-blank form-group" style="border:0px none; background-color:transparent;">
                <!-- 用ui:repeat替换c:forEach,遍历hm2的entry集合 -->
                <ui:repeat var="entry" value="#{tempBean.hm2.entrySet()}">
                    <h:panelGroup>
                        <p:commandLink>
                            <p:graphicImage style="height: 280px; width: 280px; margin-right: 10px;"
                                            title="#{entry.value.name}" value="#{entry.value}" stream="false" cache="false"/>
                            <p:ajax event="click" listener="#{tempBean.handlePictureSelect(entry.value.name)}"
                                    process="@this" update="dlg"/>
                        </p:commandLink>
                        <p:commandButton value="Remove" ajax="true"
                                         actionListener="#{tempBean.removePicture(entry.key)}"
                                         update="graphicImageCustomerPicturePanel" style="width: 280px"/>
                    </h:panelGroup>
                </ui:repeat>
            </p:panelGrid>
            <!-- 以下fileUpload和按钮代码保持不变 -->
            <p:fileUpload auto="true" mode="advanced" update="graphicImageCustomerPicturePanel"
                          fileUploadListener="#{tempBean.handleFileUploadCustomerPicture}" required="false"
                          requiredMessage="File Should not be empty!" id="pictureUploadCustomerPicture"
                          value="#{tempBean.uploadedFileCustomerPicture}">
            </p:fileUpload>
            <p:commandButton value="Save Pictures" action="#{tempBean.savePictures('save')}" ajax="false">
                <f:param name="reportTitle" value="Manage Customers"/>
            </p:commandButton>
            <p:commandButton value="Update Pictures" action="#{tempBean.savePictures('update')}" ajax="false">
                <f:param name="reportTitle" value="Manage Customers"/>
            </p:commandButton>
        </div>
    </h:panelGroup>
</h:form>
  1. 确保Bean是@ViewScoped
    你的托管Bean必须使用@ViewScoped注解(而不是@RequestScoped),这样Bean的状态会在整个视图生命周期中保持,Ajax请求不会重置hm1和hm2集合。如果之前是@RequestScoped,删除操作看似后台执行,但实际上是在新的Bean实例上操作,当前视图的Bean状态并没有改变。

  2. 验证辅助方法完整性
    确保你的cloneInputStreamAndDefaultStreamedContent方法是完整的(你提供的代码片段末尾不完整),这个方法负责克隆输入流和生成DefaultStreamedContent,只有它正常工作,剩余的图片才能正确渲染。

额外说明

你已经设置了p:graphicImage的cache="false",这一点做得很好,它能避免浏览器缓存已删除的图片,确保页面显示最新的内容。

内容的提问来源于stack exchange,提问作者Usman Aslam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:27:23