Это кажется довольно стандартным вопросом, и, вероятно, его задавали раньше, но мне было трудно его найти, потому что его трудно определить словами. Так что, если это дубликат, перенаправьте меня!
Я использую Vaadin для создания этого веб-приложения, но это не должно иметь значения для рассматриваемой проблемы, если только нет лучшего способа решить эту проблему с помощью магии Vaadin.
У меня три класса:
- Стол
- ФильтрГенератор
- Контейнер
Мой «дизайн» выглядит так:
- Контейнер добавляет в свой конструктор некоторые свойства (заголовки столбцов).
- FilterGenerator @Inject the Container (чтобы использовать метод getDistinct () контейнера, который получает отдельные элементы из контейнера - чтобы красиво представить их в ComboBox в фильтре) < / em>
- Таблица @Inject the FilterGenerator (для table.setFilterGenerator (filterGenerator))
- Таблица @Inject the Container и вызывает метод контейнеров addItems () для добавления элементов в контейнер.
- Таблица затем добавляет контейнер в качестве источника данных.
Что происходит?
Теперь у меня должна быть таблица с ComboBox в заголовке столбца, представляющая различные значения для фильтрации.
Я получаю таблицу с ComboBox в заголовке столбца, в которой ничего не представлено в ComboBox, потому что в ComboBox нет элементов.
Это неудивительно, потому что, когда FilterGenerator вызывает метод Containers getDistinct (), он возвращает пустую карту <Column, items>
, потому что во время @Inject в FilterGenerator таблица не вызвала метод Containers addItems () , поэтому Контейнер в этот момент будет пустым.
Вопрос
Как мне разработать это приложение, если я хочу, чтобы компонент (FilterTable) получал что-то от второго компонента (Container), когда третий компонент (Table) - это @ Inject-ing обоих вышеупомянутых компонентов, и крайне важно, чтобы второй компонент (Контейнер) уже был инициализирован, когда первый компонент (FilterGenerator) что-то получает от него?
Я мог бы:
В таблице просто создайте
new
FilterGenerator. Это сработает, но это не очень хорошо. Например, что произойдет, если какой-то другой компонент захочет использовать FilterGenerator?Вернитесь к xml-конфигурации, чтобы «вручную» создать экземпляры в правильном порядке. Это вероятно сработает (если я правильно помню), но создание экземпляра в зависимости от порядка элементов в вашем XML-файле мне не очень нравится.
Используйте «программную инъекцию», используя ApplicationContext.getBean () в коде. Это, наверное, было бы даже хуже, чем вышеперечисленные альтернативы?
Есть ли у кого-нибудь хорошие предложения, как разрешить эту треугольную драму?
Вот соответствующий код:
Стол
@Component
@Scope("session")
public class SampleAppMainTable extends FilteringTable {
@Inject
private SampleAppMainTableContainer sampleAppMainTableContainer;
@Inject
private SampleAppService sampleAppService;
@Inject
private SampleAppMainTableFilterGenerator sampleAppMainTableFilterGenerator;
public SampleAppMainTable() {
//...setting up the table
}
@PostConstruct
public void PostConstruct() throws GeneralSecurityException {
addMainTableItems();
setupMainTable();
}
public void setupMainTable() {
this.setFilterGenerator(sampleAppMainTableFilterGenerator);
sampleAppMainTableFilterGenerator.getCustomFilterComponent("Sample Id");
this.setContainerDataSource(sampleAppMainTableContainer);
}
public void addMainTableItems() {
sampleAppMainTableContainer.addItemsToContainer(sampleAppService.getAllSamples());
}
}
Контейнер
@Component
@Scope("prototype")
public class SampleAppMainTableContainer extends IndexedContainer {
public void addItemsToContainer(List<Sample> samples) {
// adding items to the container...
}
public Map<String, List<String>> getDistinctProperties() {
// extracting distinct items from the table...
}
}
Генератор фильтров
@Component
@Scope("session")
public class SampleAppMainTableFilterGenerator implements FilterGenerator {
@Inject
SampleAppMainTableContainer sampleAppMainTableContainer;
private List<String> aList = null;
@Override
public AbstractField<?> getCustomFilterComponent(Object propertyId) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
map = sampleAppMainTableContainer.getDistinctProperties();
if (propertyId.equals("Sample Id")) {
ComboBox sampleIdCB = new ComboBox();
BeanItemContainer<String> dataList = new BeanItemContainer<String>(String.class);
List<String> aList = map.get("Sample Id");
dataList.addAll(aList);
sampleIdCB.setContainerDataSource(dataList);
sampleIdCB.setImmediate(true);
return sampleIdCB;
}
return null;
}
// other overridden methods needed...
}
FilterGenerator
имеет состояние, тогда как он должен быть без состояния? - person M. Deinum   schedule 27.09.2013new FilterGenerator(container)
в классе Table, все будет работать как шарм. - person Roger   schedule 27.09.2013