ui:repeat не работает внутри h:dataTable

У меня проблема с ui:repeat в теге h:dataTable. У меня есть одна коллекция с именами полей и другая с данными. Поэтому я сопоставляю их по индексам. Когда я загружаю страницу, выдается исключение OutOfBoundsException. Но когда я помещаю filingCabinetManagerBean.filingCabinet.schema.fields.indexOf(schemaField) вне ui:repeat, он отображает правильные индексы. Итак, я попытался разделить его и объявил ui:param, а также c:set переменными, но та же проблема. cardData атрибут factCard не нулевой и не пустой, в нем 7 элементов, я уже отладил его. Итак, у вас есть идеи, в чем может быть проблема?

PS: Когда я меняю ui:repeat на h:dataTable, он работает. И самое главное, идентичная конструкция используется на другой странице JSF, и она работает, разница только в том, что я получаю cardData из карты, на которую ссылается одна внешняя таблица данных, поэтому это не свойство Bean(dot) и так далее, а только variable(dot) скоро.

Есть идеи? Спасибо за помощь. :)

<p:panel header="#{fileUploadBean.actualCard.id}">

        <h:dataTable value="#{filingCabinetManagerBean.filingCabinet.schema.fields}" var="schemaField" style="vertical-align: top">

            <h:column><h:outputText value="#{schemaField.fieldTitle}:" style="font-size: 20px;font-weight: bold"/></h:column>
            <h:column>
                <ul>
                    <ui:repeat value="#{fileUploadBean.actualCard.cardData.get(filingCabinetManagerBean.filingCabinet.schema.fields.indexOf(schemaField)).data}" var="data">
                        <li><h:outputText value="#{data.string}"/></li>
                    </ui:repeat>
                </ul>     
            </h:column>
        </h:dataTable>


person Xenon    schedule 24.04.2014    source источник
comment
Какая реализация/версия JSF? Пробовали последнюю? В ‹ui:repeat› было много ошибок в Mojarra, большинство из которых уже должно быть устранено в последней версии 2.2.12. Текущий ответ показывает только обходной путь, а не решение. Тем не менее, делать бизнес-логику в геттере — плохая идея. Вам лучше переработать свой контроллер, чтобы предварительно заполнить именно ту модель, которую ожидает представление, а не позволять представлению заполнять модель через геттеры (что просто неэффективно). См. также stackoverflow.com/questions/2090033/   -  person BalusC    schedule 23.10.2015


Ответы (1)


<ui:repeat> не работает внутри <h:dataTable>, потому что value из <ui:repeat> извлекается с использованием var из <h:dataTable>.

По неясной причине <h:dataTable> правильно выполняет итерацию для всех объектов списка плюс в последний раз со значением null. Эта последняя итерация ломает <ui:repeat>.

Решение состоит в том, чтобы справиться с этим при получении value из ui:repeat. Например, если у вас есть что-то вроде:

<h:dataTable value="#{someBean.parentObjList}" var="obj">
  <h:column>
    <ui:repeat value="#{someBean.getChildren(obj)" var="child" >
       ...
    </ui:repeat>
  </h:column>
</h:dataTable>

И в контроллере:

public List<ChildObj> getChildren(ParentObj obj) {
  return parentObjService.findAllFor(obj);
}

Тогда вам нужно заменить его на:

public List<ChildObj> getChildren(ParentObj obj) {
  if (obj == null)
    return new ArrayList<ChildObj>(); // return empty ArrayList to avoid crashing
  else 
    return parentObjService.findAllFor(obj);
}
person ForguesR    schedule 23.10.2015