将 <span> 放入 <p:panelGrid> 会导致显示 "weird"

Putting <span> inside a <p:panelGrid> causes "weird" display

我想创建具有 ajax 事件更新的动态表单。因此dynamic-id很重要。但是,将 id 属性绑定到 bean 值会导致 Empty Id 异常。我看到建议使用 html 的 Whosebug 问题之一。所以我用了跨度。

xhtml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui" template="../../templates/ui.xhtml">

    <ui:define name="content">
        <h:form id="testform">
            <ui:repeat value="#{repeat.questions}" var="question">
                <p:panelGrid columns="2">
                    <p:outputLabel value="#{question.label}"/>

                    <span id="#{question.questionCode}">
                        <p:inputText value="#{repeat.values[question.questionCode]}"
                                     rendered="#{question.type == 'TEXT'}">
                            <p:ajax event="blur" update="#{question.dependentQuestionCode}"
                                    disabled="#{empty question.dependentQuestionCode}"/>
                        </p:inputText>

                        <p:password value="#{repeat.values[question.questionCode]}"
                                    rendered="#{question.type == 'SECRET'}">
                        </p:password>

                        <p:inputTextarea value="#{repeat.values[question.questionCode]}"
                                         rendered="#{question.type == 'TEXTAREA'}">
                        </p:inputTextarea>

                        <p:selectOneRadio value="#{repeat.values[question.questionCode]}"
                                          rendered="#{question.type == 'RADIO'}" layout="grid" columns="1">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectOneRadio>

                        <p:selectOneMenu value="#{repeat.values[question.questionCode]}"
                                         rendered="#{question.type == 'SELECTONE'}">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectOneMenu>

                        <p:selectManyMenu value="#{repeat.values[question.questionCode]}"
                                          rendered="#{question.type == 'SELECTMANY'}">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectManyMenu>

                        <p:selectBooleanCheckbox
                                value="#{repeat.values[question.questionCode]}"
                                rendered="#{question.type == 'CHECKONE'}"/>

                        <p:selectManyCheckbox value="#{repeat.values[question.questionCode]}"
                                              rendered="#{question.type == 'CHECKMANY'}">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectManyCheckbox>
                     </span>
                </p:panelGrid>
            </ui:repeat>

            <p:commandButton value="Submit" actionListener="#{repeat.submit}"/>
        </h:form>
    </ui:define>
</ui:composition>

但是,显示很奇怪。它关闭了每次迭代中的跨度。为什么跨度关闭标签之前不合理地关闭了跨度?

<h|p:panelGrid> 只将真正的 JSF 子组件分成列,而不是普通的 HTML 元素。

<span>(或更好,<div>)作为 <ui:repeat> 的直接子代。

<ui:repeat value="#{bean.questions}" var="question">
    <div id="#{question.code}">
        <p:panelGrid>
            ...
        </p:panelGrid>
    </div>
</ui:repeat>