これはかなり標準的な質問のように感じられ、おそらく以前に尋ねられたことがありますが、言葉で定義するのが難しいため、見つけるのが難しいと感じました. これが重複している場合は、先に進んでリダイレクトしてください!
私は Vaadin を使用してこの Web アプリを構築していますが、Vaadin の魔法によってこれを解決するより良い方法がない限り、目前の問題には関係ありません。
私は3つのクラスを持っています:
- テーブル
- FilterGenerator
- 容器
私の「デザイン」は次のようになります。
- コンテナーは、コンストラクターでいくつかのプロパティ (列ヘッダー) をそれ自体に追加します。
- FilterGenerator @Inject the Container (コンテナから個別のアイテムを取得するコンテナの getDistinct() メソッドを使用するため - それらをフィルタの ComboBox に適切に表示するため)
- テーブル@Inject FilterGenerator ( table.setFilterGenerator(filterGenerator) にするため)
- Table @Inject the Container を呼び出し、コンテナーの addItems() メソッドを呼び出して項目をコンテナーに追加します。
- その後、テーブルはコンテナをデータソースとして追加します
何が起こるのですか?
ここで必要なのは、列ヘッダーに ComboBox があり、フィルター処理する個別の値を示すテーブルです。
私が得たのは、列ヘッダーに ComboBox を含むテーブルで、ComboBox に項目がないため、ComboBox には何も表示されません。
FilterGenerator が Containers getDistinct() メソッドを呼び出すと、空のマップ<Column, items>
back が取得されるため、これは驚くべきことではありません。 なぜなら、FilterGenerator で @Inject を実行した時点で、Table は Containers の addItems() メソッドを呼び出していないためです。そのため、コンテナはこの時点で空になります。
質問
コンポーネント (FilterTable) が 2 番目のコンポーネント (コンテナー) から何かを取得するようにしたい場合、3 番目のコンポーネント (テーブル) が前述のコンポーネントの両方を @Inject し、2 番目のコンポーネント (コンテナー) が重要である場合、このアプリケーションをどのように設計すればよいですか? ) 最初のコンポーネント (FilterGenerator) がそこから何かを取得したときに、すでに初期化されていますか?
私はできた:
テーブルで、単純に
new
FilterGenerator を作成します。これは機能しますが、あまり良くありません。たとえば、他のコンポーネントが FilterGenerator を使用したい場合はどうなりますか?インスタンスを正しい順序で「手動で」作成するには、xml-configuration に戻ります。これはおそらく機能しますが (私の記憶が正しければ)、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...
}