0

这感觉像是一个非常标准的问题,可能以前也有人问过,但我发现很难找到,因为很难用语言来定义。因此,如果这是重复的,请继续重定向我!

我正在使用 Vaadin 构建这个 Web 应用程序,但这与手头的问题无关紧要,除非有更好的方法通过一些 Vaadin 魔法来解决这个问题。

我有三个班级:

  • 桌子
  • 过滤器生成器
  • 容器

我的“设计”是这样的:

  • Container在其构造函数中为自身添加了一些属性(列标题)
  • FilterGenerator @Inject Container (为了使用 Container 的 getDistinct() 方法从容器中获取不同的项目 - 为了在过滤器的 ComboBox 中很好地呈现它们)
  • 表@Inject FilterGenerator 为了table.setFilterGenerator(filterGenerator))
  • Table @Inject Container 并调用容器的addItems() 方法向容器中添加项目
  • 然后将容器添加为数据源

怎么了?

我现在应该有一个在列标题中有一个 ComboBox 的表格,呈现不同的值进行过滤。

我得到的是一个在列标题中有一个 ComboBox 的表,在 ComboBox 中没有显示任何内容,因为 ComboBox 中没有项目。

这并不奇怪,因为当FilterGenerator调用Containers的getDistinct()方法时,会得到一个空的<Column, items>返回map,因为在FilterGenerator中@Inject的时候,Table还没有调用Containers的addItems()方法,所以此时 Container 将是空的。

问题

如果我希望一个组件(FilterTable)从第二个组件(Container)中获取某些东西,我应该如何设计这个应用程序,而第三个组件(Table)是 @Inject 两个上述组件,并且第二个组件(Container)至关重要) 当第一个组件 (FilterGenerator) 从中获取一些东西时已经被初始化了吗?

我可以:

  • 在表中,只需创建一个newFilterGenerator。这会起作用,但它不是很好。例如,如果某个其他组件想要使用 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...
}
4

1 回答 1

0

我认为您的问题是您在注入阶段执行处理逻辑。您应该等到一切都设置好后再进行处理。您可以通过将处理逻辑从构造函数移动到初始化方法并使用@Inject 标记此方法来执行此类操作。根据定义,注入是在方法上最后完成的,即在注入器调用方法时,所有字段都被注入。

于 2013-09-27T11:30:56.197 回答