简体   繁体   English

为什么 <ui:repeat> 与java.util.Iterator不兼容?

[英]Why does <ui:repeat> not work with java.util.Iterator?

Why does JSF2/Facelet's ui:repeat not accept java.util.Iterator's for value? 为什么JSF2 / Facelet的ui:repeat不接受java.util.Iterator的值? One can hide so much implementation and memory conservation behind an Iterator since length need not be known, it would be so useful to have. 因为不需要知道长度,所以可以在Iterator后面隐藏这么多的实现和内存保存,拥有它会非常有用。 But instead I need to convert my Iterators to Lists and throw away all my advantages in order to ui:repeat. 但是相反,我需要将Iterators转换为Lists并放弃所有优点,以便使用ui:repeat。

There are probably phase or timing or Serializable reasons, but my skimming of the docs that are available do not give those reasons. 可能有阶段或时序或可序列化的原因,但是我对可用文档的略读并没有给出这些原因。 Do we not yet have the science to make this impossibility possible? 我们是否还没有使这种可能性成为可能的科学?

<ui:repeat> doesn't support java.util.Iterator . <ui:repeat>不支持java.util.Iterator
Have look at UIRepeat.getDataModel() source code: 看一下UIRepeat.getDataModel()源代码:

 private DataModel getDataModel() {
    if (this.model == null) {
        Object val = this.getValue();
        if (val == null) {
            this.model = EMPTY_MODEL;
        } else if (val instanceof DataModel) {
            //noinspection unchecked
            this.model = (DataModel<Object>) val;
        } else if (val instanceof List) {
            //noinspection unchecked
            this.model = new ListDataModel<Object>((List<Object>) val);
        } else if (Object[].class.isAssignableFrom(val.getClass())) {
            this.model = new ArrayDataModel<Object>((Object[]) val);
        } else if (val instanceof ResultSet) {
            this.model = new ResultSetDataModel((ResultSet) val);
        } else {
            this.model = new ScalarDataModel<Object>(val);
        }
    }
    return this.model;
}

You can make <ui:repeat> work with an Iterator, but you must wrap the Iterator with an object that extends javax.faces.model.DataModel. 您可以使<ui:repeat>与Iterator一起使用,但是必须用扩展javax.faces.model.DataModel的对象包装Iterator。 Here is my IteratorDataModel class that can make any Iterator accessible to <ui:repeat>. 这是我的IteratorDataModel类,可以使<ui:repeat>可以访问任何迭代器。 I tested this with JSF 2.1.26: 我使用JSF 2.1.26对此进行了测试:

/**
 * Make a DataModel out of an Iterator that may be used with JSF's ui:repeat tag
 *
 * This DataModel does not support the use of offset or step attributes in the
 * ui:repeat tag, and the size attribute in ui:repeat, when used with this DataModel, 
 * will report an inaccurate value.
 *
 * Copyright (c) 2014 Woldrich, Inc.
 * Licensed under MIT (https://clubcompy.com/wcm/license/mit.txt)
 * 
 * @author Dave Woldrich
 */
public class IteratorDataModel<T> extends DataModel<T> {
    private static final Logger logger = LogManager.getLogger(IteratorDataModel.class);

    private Iterator<?> iterator;
    private int rowIndex; 
    private T item;

    public IteratorDataModel(Iterator<?> iterator) {
        setWrappedData(iterator);      
    }

    @Override
    public int getRowCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public T getRowData() {
        return this.item;
    }

    @Override
    public int getRowIndex() {
        if(this.rowIndex == -1 && this.iterator.hasNext()) {
            this.setRowIndex(0);
        }

        if(logger.isTraceEnabled()) {
            logger.trace("getRowIndex returns " + this.rowIndex);
        }

        return this.rowIndex;
    }

    @Override
    public Object getWrappedData() {
        return this.iterator;
    }

    @Override
    public boolean isRowAvailable() {
        boolean hasNext = this.item != null || this.iterator.hasNext(); 

        if(logger.isTraceEnabled()) {
            logger.trace("isRowAvailable " + hasNext);
        }

        return hasNext;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void setRowIndex(int newIndex) {
        if(logger.isTraceEnabled()) {
            logger.trace("setRowIndex (" + newIndex + ")");
        }

        if(newIndex == this.rowIndex+1) {
            this.rowIndex = newIndex;

            this.item = (T) (this.iterator.hasNext() ? this.iterator.next() : null);
        } 
        else if(newIndex > -1 || newIndex != this.rowIndex) {
            if(logger.isTraceEnabled()) {
                logger.trace("setRowIndex not incrementing by 1 as expected, ignored");            
            }
        }
    }

    @Override
    public void setWrappedData(Object data) {
        this.iterator = (Iterator<?>) data;
        this.rowIndex = -1;
        this.item = null;
    }    
}

And in your facelets code, for example, you may use: 例如,在facelets代码中,您可以使用:

<ul>
    <ui:repeat value="#{chatRoom.allComments}" var="aComment" varStatus="status">
        <li><h:outputText value="#{aComment.text}" /></li>
    </ui:repeat>
</ul>

where chatRoom.getAllComments() would return a IteratorDataModel<Comment> that is constructed passing an Iterator<Comment> . 其中chatRoom.getAllComments()将返回通过IteratorDataModel<Comment>构造的Iterator<Comment>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么java.util.Iterator不会在嵌套循环中重置? - Why java.util.Iterator does not reset in a nested loop? 关闭java.util.Iterator - Closing a java.util.Iterator java.util.Iterator但不能导入java.util.Iterator - java.util.Iterator but cannot import java.util.Iterator java.util.Iterator 的实现是否使用 State 模式? - Does the implementation of the java.util.Iterator use the State pattern? 摆脱 java.util.Iterator - Getting rid of java.util.Iterator 未经检查的分配:“匿名java.util.Iterator”到“ java.util.Iterator” <java.lang.Integer> &#39; - Unchecked assignment: 'anonymous java.util.Iterator' to 'java.util.Iterator<java.lang.Integer>' java.util.Iterator<java.lang.Object[]> 无法转换为 java.util.Iterator<T[]> - java.util.Iterator<java.lang.Object[]> cannot be converted to java.util.Iterator<T[]> 在NeoMAD项目中使用java.util.Iterator时出错 - Error when using java.util.Iterator in a NeoMAD project 不兼容的类型-找到了java.util.Iterator(Lot),但是需要使用java.util.Iterator(java.lang.String) - incompatible types - found java.util.Iterator(Lot) but expected java.util.Iterator (java.lang.String) 列表的迭代器同时实现了 Kotlin.Collection.Iterator 以及 Java.util.Iterator? - list's iterator is implementing both Kotlin.Collection.Iterator as well as Java.util.Iterator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM