【问题标题】:p:inputText inside ui:repeat works only for last elementp:inputText inside ui:repeat 仅适用于最后一个元素
【发布时间】:2017-09-30 16:20:37
【问题描述】:

我正在使用 JSF 和 PrimeFaces 创建一个图片库。我在里面使用 ui:repeat 和 p:graphicImage 来显示从 db 检索到的图像列表。每个图像都有一个在 ui:repeat 中定义的点击 p:dialog(及其各自的 id)。在 p:dialog 中,我再次显示了单击的图像,并且还有一个 h:form,其中有一个 p:inputText 和一个 p:commandbutton,用于将 p:inputText 的文本保存到 bean 的 String 属性中。问题是只有 ui:repeat 显示的列表的最后一个图像“看到”了 bean 并设置了属性。如果在 ui:repeat 显示的最后一个图像的对话框中,我写了一条评论并单击命令按钮,它会设置 bean 的字符串文本,如果我对其他图像执行相同操作,则字符串文本为空。也许这是bean可见性的问题。我尝试为 bean 使用不同的范围,但它仍然不起作用。

这是 JSF 代码:

    <ui:repeat value="#{imageShowController.images}" var="img">
    <h:outputLink value="javascript:void(0)"
        onclick="PF('picDialog-#{img.id}').show();">
        <p:graphicImage value="#{imageShowController.streamedContent}"
            width="250" height="250" cache="false">
            <f:param name="id" value="#{img.id}" />
        </p:graphicImage>
    </h:outputLink>
    <p:dialog id="picDialog-#{img.id}" widgetVar="picDialog-#{img.id}"
        width="500" height="500">
        <p:graphicImage value="#{imageShowController.streamedContent}">
            <f:param name="id" value="#{img.id}" />
        </p:graphicImage>
        <h:form>
            <h:panelGrid columns="2" cellpadding="5">
                <p:inputText value="#{imageShowController.txt}" />
                <p:commandButton value="Submit comment"
                    action="#{imageShowController.saveComment()}">
                    <f:param name="id" value="#{img.id}" />
                </p:commandButton>
            </h:panelGrid>
        </h:form>
    </p:dialog>
</ui:repeat>

这是 bean (Java):

@ManagedBean
@RequestScoped
public class ImageShowController {
    @Inject
    private UserSessionBean userSession;
    @Inject
    private ImageDaoService imagedao;
    @Inject
    private CommentDaoService commentdao;

    private List<Image> images;
    private String text;
    private String id;

    @PostConstruct
    public void init() throws SQLException {
        images = new ArrayList<>();
        images = imagedao.findImagesByUserId( userSession.getUserId() );
    }

    public void saveComment(){
        FacesContext context = FacesContext.getCurrentInstance();
        String id = 
        context.getExternalContext().getRequestParameterMap().get("id");

        Comment comment = new Comment();
        comment.setText(text);
        comment.setDate(new Date());
        comment.setImage(imagedao.findById(Long.valueOf(id)).get(0));
        commentdao.addComment(comment);     
    }

    public StreamedContent getStreamedContent() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            return new DefaultStreamedContent();
        }
        else {
            id = 
            context.getExternalContext().getRequestParameterMap().get("id");
            System.out.println("INDEX: "+id);

            byte [] b = null;
            for (int i = 0; i < images.size(); i++) {
                if(images.get(i).getId() == Long.valueOf(id)){
                    b = images.get(i).getPicture();
                    break;
                }
            }
            return new DefaultStreamedContent(new ByteArrayInputStream(b));
        }
    }
}

【问题讨论】:

  • 您不应该为每次迭代创建一个对话框。把它放在外面,让你控制它的变量。我在这里看到的问题虽然没有在您的代码中显示,但您可能有一个围绕 ui:repeat 的表单,并且您的对话框也在其中包含一个表单,您不能在另一个表单中包含一个表单。
  • 感谢您的回答。 ui:repeat 不在表单内,对话框内只有表单。我已经尝试将对话框放在 ui:repeat 之外,但问题是我需要将相应图像的 id 传递给对话框,如果对话框在外面,则不可能。我该怎么做?
  • 尝试从 PostConstruct 注释方法 init 中删除 throws SQLException。看看会发生什么。
  • 我删除了 throws SQLException 但没有任何变化。 @Kukeltje 我不认为我的问题是重复的,因为我在问如何从 jsf 设置 bean 属性,而在另一个问题中,它被问到如何获取和显示从 bean 到 jsf 的属性。这对我有用。我的问题是该集合仅适用于 ui:repeat 的最后一个元素

标签: jsf primefaces jsf-2


【解决方案1】:

我使用 JSTL 的标签 c:forEach 而不是 ui:repeat 解决了问题。有效!!

【讨论】:

    最近更新 更多