Как реализовать зависимости между двумя компонентами selectOneMenu? [Дубликат]

Чтобы избежать всех отрицательных эффектов инициализации двойной комбинации, например:

  1. Сломанная «равна» совместимости.
  2. При выполнении прямых назначений никаких проверок не выполнялось.
  3. Возможные утечки памяти.

делать следующие вещи:

  1. Сделать отдельный класс «Builder» особенно для инициализации двойной привязки.
  2. Объявить поля со значениями по умолчанию.
  3. Поместить метод создания объекта в этот класс.

Пример:

public class MyClass {
    public static class Builder {
        public int    first  = -1        ;
        public double second = Double.NaN;
        public String third  = null      ;

        public MyClass create() {
            return new MyClass(first, second, third);
        }
    }

    protected final int    first ;
    protected final double second;
    protected final String third ;

    protected MyClass(
        int    first ,
        double second,
        String third
    ) {
        this.first = first ;
        this.second= second;
        this.third = third ;
    }

    public int    first () { return first ; }
    public double second() { return second; }
    public String third () { return third ; }
}

Использование :

MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();

Преимущества:

  1. Просто использовать.
  2. Не разрывает совместимость «равно».
  3. Вы может выполнять проверки в методе создания.
  4. Отсутствует утечка памяти.

Недостатки:

  • Нет.

И, как результат, у нас самый простой шаблон java-строителя.

См. все образцы в github: java-sf-builder-simple-example

3
задан BalusC 5 November 2015 в 09:15
поделиться

1 ответ

Вы можете использовать <f:ajax> для этого. При вложенности в входной компонент, такой как <h:selectOneMenu>, он по умолчанию будет вызываться при изменении входного значения. Вы можете указать метод listener, который может предварительно заполнить данные для следующего компонента на основе текущего входного значения, и вы можете указать идентификатор клиента этого следующего компонента в render, чтобы показать предварительно заполненные данные.

<h:selectOneMenu value="#{bean.country}">
    <f:selectItems value="#{bean.countries}" />
    <f:ajax listener="#{bean.changeCountry}" render="cities" />
</h:selectOneMenu>
<h:panelGroup id="cities">
    <h:selectOneMenu value="#{bean.city}" rendered="#{not empty bean.cities}">
        <f:selectItems value="#{bean.cities}" />
    </h:selectOneMenu>
</h:panelGroup>

Боб должен быть, по крайней мере, в области видимости (не запрос):

@ManagedBean
@ViewScoped
public class Bean implements Serializable {

    private String country; // +getter+setter
    private String city; // +getter+setter
    private List<String> countries; // +getter
    private List<String> cities; // +getter

    @EJB
    private LocationService locationService;

    @PostConstruct
    public void init() {
        countries = locationService.getCountries();
    }

    public void changeCountry() {
        cities = locationService.getCities(country);
    }

    // ...
}

Вы можете, конечно, также использовать Map<String, String> вместо List<String>. Ключ карты становится меткой опции, а значение карты становится значением параметра. Вам нужно только иметь в виду, что HashMap по своей природе неупорядочен. Вы предпочитаете использовать LinkedHashMap вместо этого, чтобы отображать элементы в порядке ввода Map.

См. Также:

13
ответ дан Community 18 August 2018 в 16:44
поделиться
  • 1
    +1 для @BalusC, ответ очень ясен, и ваш блог объясняет это гораздо глубже. :) Что делать, если у меня есть 100 пользователей, обращающихся к одной и той же странице, я теряю память, создавая 100 разных объектов! Есть ли способ оптимизации, чтобы мы могли использовать Object на уровне приложения. – 09Q71AO534 18 April 2015 в 06:36
  • 2
    @ 09Q71AO534: просто поместите данные с областью приложения, например #{bean.countries}, в компонентный компонент и используйте кеш-память второго уровня JPA для городов. – BalusC 20 April 2015 в 07:31
  • 3
    @BalusC Знаете ли вы, какой пакет Java мне нужно вставить для private LocationService locationService;? – Peter Penzov 11 March 2016 в 14:37
  • 4
    @Peter: Это просто ваш собственный класс обслуживания. Имя было просто образцовым, как Bean – BalusC 11 March 2016 в 14:46
  • 5
    @BalusC Возможно ли изменить второй выпадающий список без фактического представления (и настройки) первого? (с помощью execute = "@ none"). Если моя форма находится внутри всплывающего окна, которое может быть закрыто / отменено, я не хочу, чтобы какое-либо изменение раскрывающегося списка 1-го (ajax) было применено к моей модели до тех пор, пока «save & quot; кнопка отправки. – Xavier Dury 17 April 2018 в 07:57
Другие вопросы по тегам:

Похожие вопросы: