JSF: Как связать многие из h: selectBooleanCheckbox? - PullRequest
7 голосов
/ 26 октября 2010

У меня проблема с привязкой списка h: selectBooleanCheckbox к моему бину. Кто-нибудь помогает?

Это не работает:

<ui:repeat value="#{cartBean.productsList}" var="cartProduct" varStatus="i">
   <h:selectBooleanCheckbox binding="#{cartBean.checkboxes[i.index]}" />
</ui:repeat>

public class CartBean extends BaseBean {
  public List<Product> getProductsList() {...}

  private HtmlSelectBooleanCheckbox[] checkboxes;
  public HtmlSelectBooleanCheckbox[] getCheckboxes() {
    return checkboxes;
  }
  public void setCheckboxes(HtmlSelectBooleanCheckbox[] checkboxes) {
    this.checkboxes = checkboxes;
  }
}

Я получаю ошибку:

javax.faces.FacesException: javax.el.PropertyNotFoundException: /WEB-INF/flows/main/cart.xhtml @26,97 binding="#{cartBean.checkboxes[i.index]}": Target Unreachable, 'checkboxes' returned null

Я решил свою проблему. Я использовал код, как показано ниже, и получаю то, что хочу (спасибо блогу BalusC - http://balusc.blogspot.com/2006/06/using-datatables.html#SelectMultipleRows):

<ui:repeat value="#{cartBean.productsList}" var="cartProduct" varStatus="i">
  <h:selectBooleanCheckbox value="#{cartBean.selectedIds[cartProduct.id]}" />
</ui:repeat>

public class CartBean extends BaseBean {
  private Map<Integer, Boolean> selectedIds = new HashMap<Integer, Boolean>();
  public Map<Integer, Boolean> getSelectedIds() {
    return selectedIds;
  }
}

Ответы [ 2 ]

2 голосов
/ 15 ноября 2013

Ваша конкретная проблема вызвана тем, что атрибут 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>

См. Также:

0 голосов
/ 26 октября 2010

Не знаю, можно ли связывать элементы, хранящиеся в массиве.Но в вашем коде проблема в том, что ваш HtmlSelectBooleanCheckbox[] равен null.Поэтому, возможно, измените ваш код Java на:

public HtmlSelectBooleanCheckbox[] getCheckboxes() {
    if (checkboxes == null) {
        checkboxes = new HtmlSelectBooleanCheckbox[getProductsList().size()];
    }
    return checkboxes;
}

, но я действительно не уверен, будет ли он работать ... Возможно, решение состоит в том, чтобы не связывать ваши элементы HtmlSelectBooleanCheckbox в коде Java.Зачем вам их связывать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...