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

Performance 如何根据呈现时可用的值有条件地将组件添加到JSF组件树中?,performance,jsf,datatable,components,jsf-2.2,Performance,Jsf,Datatable,Components,Jsf 2.2,如何在标准JSF数据表中有条件地选择html输入的类型,而不必考虑未渲染组件的开销?我有一个解决办法,但这对我来说还不够好 示例测试bean: @Named @ViewScoped public class TestBean implements Serializable { private static final long serialVersionUID = 1L; private Map<Descriptor, Object> values = new Ha

如何在标准JSF数据表中有条件地选择html输入的类型,而不必考虑未渲染组件的开销?我有一个解决办法,但这对我来说还不够好

示例测试bean:

@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);
        }
    }
}
@Named
@视域
公共类TestBean实现了可序列化{
私有静态最终长serialVersionUID=1L;
私有映射值=新的HashMap();
公共TestBean(){
put(新描述符(“整数值”、“整数”),10);
put(新描述符(“字符串值”、“字符串”)、“示例字符串”);
value.put(新描述符(“布尔值”、“布尔”),Boolean.TRUE);
}
公共映射getValues(){
返回值;
}
公共类描述符实现可序列化{
私有静态最终长serialVersionUID=1L;
私有字符串名称;
私有字符串类型;
公共描述符(字符串名称、字符串类型){
this.name=名称;
this.type=type;
}
公共字符串getName(){
返回名称;
}
公共字符串getType(){
返回类型;
}
@凌驾
公共布尔等于(对象o){
if(this==o){
返回true;
}
如果(o==null | |!TestBean.class.equals(o.getClass())){
返回false;
}
描述符other=(描述符)o;
返回Objects.equals(name,other.name)&&
Objects.equals(type,other.type);
}
@凌驾
公共int hashCode(){
返回Objects.hash(名称、类型);
}
}
}
示例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

当我需要在数据表中使用switch语句时,是否有任何方法可以减少组件的数量?换句话说:如果没有组件树中的其他(未指定的)组件,如何实现第一个示例的结果


(我使用Mojarra 2.2.8-17)

您希望在同一页面中加载多少行?您是否使用
rendered
属性进行过任何基准测试,比如1000行?尽管如此,我认为在实现分页时显示较少的行更为用户体验友好。这样可以避免您提到的开销和其他问题(假设用户输入1000个值,当发送这些值时,会话将过期,因此他必须再次登录并重做所有工作。)我希望加载1000多行。在客户端,使用javascript解决分页问题。我知道我可以通过延迟加载来实现这一点,但它增加了更多的复杂性。实际上,我想使用第三方数据表(来自Bootsfaces),并且在这个实现中没有延迟加载支持。这就是我为什么要找别的东西。没有延迟加载,我可以在表中搜索并对行进行排序。对于延迟加载解决方案,这是一件困难的事情。延迟加载与如何在托管bean中从可能依赖于DB或API的服务检索数据有关。您上面提到的问题似乎与此无关(您说希望改进JSF呈现页面本身)。我在生产中得到了一些primefaces数据表,但没有延迟加载,显示超过15K项。所有项目都是在一个查询中从DB加载的,并存储在托管bean中,页面显示不到3秒。但是,我使用分页(每页25页)并让用户按表中的任何字段进行筛选。例如,我只发回前100行,如果用户使用paginator向前移动,客户端将发送一个ajax请求并更新表。我将ui:repeat循环与呈现属性进行了比较,并将c:forEach循环与c:choose进行了比较。结果很有趣。对于ui:repeat,响应时间为2.88秒;而对于c:forEach,响应时间为20.67秒。