Ваша конкретная проблема вызвана тем, что атрибут binding
оценивается во время построения представления, в тот момент, когда исходный код XHTML превращается в дерево компонентов пользовательского интерфейса JSF, тогда как <ui:repeat>
выполняется во время визуализации представления, в этот моменткогда дерево компонентов пользовательского интерфейса JSF должно генерировать HTML.
Другими словами, #{i.index}
доступен только во время визуализации представления и оценивается как null
во время построения представления.В результате вы делаете binding="#{cartBean.checkboxes[null]}"
Здесь есть еще одна концептуальная ошибка: вы, похоже, ожидаете, что <ui:repeat>
создаст физически несколько <h:selectBooleanCheckbox>
компонентов.Это неправда.Физически есть только один <h:selectBooleanCheckbox>
, который многократно используется для создания HTML на основе текущей итерированной переменной.На самом деле, binding="#{cartBean.checkbox}"
было достаточно.Однако сбор ценностей - отдельная история.Я не буду вдаваться в подробности, но вы можете найти несколько подсказок в этом ответе: Проверить порядок элементов внутри пользовательского интерфейса: повторите .
Для того, чтобы выполнить (кажущееся) конкретное функциональное требованиегенерации физически нескольких <h:selectBooleanCheckbox>
компонентов и привязки каждого к отдельному элементу массива, вы должны использовать итерационный компонент, который выполняется во время сборки представления вместо времени визуализации представления.Это JSTL <c:forEach>
:
<c:forEach items="#{cartBean.productsList}" var="cartProduct" varStatus="i">
<h:selectBooleanCheckbox binding="#{cartBean.checkboxes[i.index]}" />
</c:forEach>
Но, в конце концов, следует максимально избегать использования binding
для свойства bean-компонента.Вместо этого используйте именно тот атрибут, который вам в конечном итоге понадобится: атрибут value
.Таким образом, вам не нужно делать HtmlSelectBooleanCheckbox#getValue()
каждый раз.Вы уже нашли правильное решение с Map<Integer, Boolean> selectedIds
:
<ui:repeat value="#{cartBean.productsList}" var="cartProduct">
<h:selectBooleanCheckbox value="#{cartBean.selectedIds[cartProduct.id]}" />
</ui:repeat>
См. Также: