如何根据渲染时可用的值有条件地将组件添加到JSF组件树中?

时间:2018-07-02 12:21:20

标签: performance jsf datatable components jsf-2.2

如何在没有未渲染组件开销的情况下有条件地选择标准JSF dataTable中html输入的类型?我有一个解决方案,但这对我来说还不够。

示例测试豆:

@Named
@ViewScoped
public class TestBean implements Serializable {
    private static final long serialVersionUID = 1L;

    private Map<Descriptor, Object> values = new HashMap<>();

    public TestBean() {
        values.put(new Descriptor("Integer value", "Integer"), 10);
        values.put(new Descriptor("String value", "String"), "example string");
        values.put(new Descriptor("Boolean value", "Boolean"), Boolean.TRUE);
    }

    public Map<Descriptor, Object> getValues() {
        return values;
    }

    public class Descriptor implements Serializable {
        private static final long serialVersionUID = 1L;
        private String name;
        private String type;

        public Descriptor(String name, String type) {
            this.name = name;
            this.type = type;
        }

        public String getName() {
            return name;
        }

        public String getType() {
            return type;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || !TestBean.class.equals(o.getClass())) {
                return false;
            }
            Descriptor other = (Descriptor) o;
            return Objects.equals(name, other.name) &&
                    Objects.equals(type, other.type);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name, type);
        }
    }
}

示例test.xhtml第1部分:

<!-- Works -->
<h:dataTable value="#{testBean.values.keySet()}" var="valueKey">
    <h:column>
        <f:facet name="header">Key</f:facet>
        <h:outputText value="#{valueKey.name}"/>
    </h:column>
    <h:column>
        <f:facet name="header">Value</f:facet>
        <h:inputText pt:type="number" pt:step="1" converter="javax.faces.Integer"
                     value="#{testBean.values[valueKey]}" rendered="#{valueKey.type eq 'Integer'}"/>
        <h:selectBooleanCheckbox value="#{testBean.values[valueKey]}" rendered="#{valueKey.type eq 'Boolean'}"/>
        <h:inputTextarea value="#{testBean.values[valueKey]}"
                         rendered="#{valueKey.type ne 'Integer' and valueKey.type ne 'Boolean'}"/>
    </h:column>
</h:dataTable>

这样,一切都可以正常工作,但是我将单个输入的组件数量增加了三倍。 (未渲染的组件仍添加到组件树中。)这是不可接受的,因为我必须使用大型数据集。在输入大量条目的情况下,响应时间很慢。所以我在寻找另一种方式,例如下面的示例:

示例test.xhtml第2部分:

<!-- Doesn't work -->
<h:dataTable value="#{testBean.values.keySet()}" var="valueKey">
    <h:column>
        <f:facet name="header">Key</f:facet>
        <h:outputText value="#{valueKey.name}"/>
    </h:column>
    <h:column>
        <f:facet name="header">Value</f:facet>
        <c:choose>
            <c:when test="#{valueKey.type eq 'Integer'}">
                <h:inputText pt:type="number" pt:step="1" converter="javax.faces.Integer"
                             value="#{testBean.values[valueKey]}"/>
            </c:when>
            <c:when test="#{valueKey.type eq 'Boolean'}">
                <h:selectBooleanCheckbox value="#{testBean.values[valueKey]}"/>
            </c:when>
            <c:otherwise>
                <h:inputTextarea value="#{testBean.values[valueKey]}"/>
            </c:otherwise>
        </c:choose>
    </h:column>
</h:dataTable>

这很好,但是在构建视图时test属性的值为null。

当我需要在dataTable中使用switch语句时,是否有任何变通的方法来减少组件数量?换句话说:如何在没有附加(未呈现)的情况下实现第一个示例的结果组件树中的组件?

(我与Mojarra 2.2.8-17一起工作)

0 个答案:

没有答案