CUBA:实体继承 [英] CUBA : entity inheritance

查看:144
本文介绍了CUBA:实体继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提供的示例实体继承"具有以下实体模型:
-客户
-公司扩展客户
-人员扩展了客户
-订单

OrderEdit屏幕显示了如何处理与可能是公司或个人的客户相关联的字段的继承.这很清楚.

但是,公司"和人"的编辑屏幕不会考虑继承:它们只是复制通常从客户"那里继承的电子邮件"字段.

鉴于我目前的所有输入,如果必须设计这些屏幕,我将提出以下方法.

1)CustomerEditFrame:带有电子邮件字段,未定义数据源

2)PersonEditScreen:
-人员数据源
-在Person数据源上映射lastName和firstName字段
-嵌入CustomerEditFrame
-将Person数据源注入CustomerEditFrame

3)CompanyEditScreen:
-公司数据源
-将行业领域映射到公司数据源
-嵌入CustomerEditFrame
-在CustomerEditFrame

中插入公司数据源

然后,CustomerEditFrame负责在引用两个子类之一的数据源中编辑它知道的字段子集.这种设计可行吗?

为了文档的完整性,我认为这应该包含在样本中,这是常见的情况.此外,这将是进行帧操作的一个很好的示例.

解决方案

您绝对正确,屏幕应该考虑实体继承,以消除重复的代码.我在此处分叉了示例项目,以演示如何使用框架来完成它./p>

customer-frame.xml包含基础实体的字段以及该实体的数据源:

 <window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.company.entityinheritance.gui.customer.CustomerFrame"
        focusComponent="fieldGroup"
        messagesPack="com.company.entityinheritance.gui.customer">
    <dsContext>
        <datasource id="customerDs"
                    class="com.company.entityinheritance.entity.Customer"
                    view="_local"/>
    </dsContext>
    <layout spacing="true">
        <fieldGroup id="fieldGroup"
                    datasource="customerDs">
            <column width="250px">
                <field id="name"/>
                <field id="email"/>
            </column>
        </fieldGroup>
    </layout>
</window>
 

CustomerFrame控制器中,有一个公共方法可以将实例设置为数据源:

 public class CustomerFrame extends AbstractFrame {

    @Inject
    private Datasource<Customer> customerDs;

    public void setCustomer(Customer customer) {
        customerDs.setItem(customer);
    }
}
 

公司编辑器company-edit.xml包含框架而不是客户"字段:

 <window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.company.entityinheritance.gui.company.CompanyEdit"
        datasource="companyDs"
        focusComponent="customerFrame"
        messagesPack="com.company.entityinheritance.gui.company">
    <dsContext>
        <datasource id="companyDs"
                    class="com.company.entityinheritance.entity.Company"
                    view="_local"/>
    </dsContext>
    <layout expand="windowActions"
            spacing="true">
        <frame id="customerFrame"
               screen="demo$Customer.frame"/>
        <fieldGroup id="fieldGroup"
                    datasource="companyDs">
            <column width="250px">
                <field id="industry"/>
            </column>
        </fieldGroup>
        <frame id="windowActions"
               screen="editWindowActions"/>
    </layout>
</window>
 

在公司"编辑器控制器中,注入了框架并将经过编辑的实例传递给它:

 public class CompanyEdit extends AbstractEditor<Company> {

    @Inject
    private CustomerFrame customerFrame;

    @Override
    protected void postInit() {
        customerFrame.setCustomer(getItem());
    }
}
 

Provided sample 'Entity Inheritance' has the following entity model:
- Customer
- Company extends Customer
- Person extends Customer
- Order

The OrderEdit screen show how to handle the inheritance for fields associated with a Customer that could be a Company or a Person. This is perfectly clear.

However, edit screens for Company and Person do not take inheritance into account : they simply duplicate 'email' field which is commonly inherited from Customer.

Given all inputs I had at this point, if I had to design these screens I would propose the following way.

1) CustomerEditFrame : with the email field, no datasource defined

2) PersonEditScreen:
- Person datasource
- map lastName and firstName fields on Person datasource
- embed CustomerEditFrame
- inject Person datasource in the CustomerEditFrame

3) CompanyEditScreen:
- Company datasource
- map industry field to Company datasource
- embed CustomerEditFrame
- inject Company datasource in the CustomerEditFrame

Then the CustomerEditFrame is responsible for editing the subset of fields it is aware of in a datasource referring either of the two subclasses. Would this design work ?

For the sake of completeness of documentation I think this should be covered by the sample, as it is common case. In addition, it would be a good sample for frame manipulation.

解决方案

You are absolutely right that screens should take entity inheritance into account to eliminate duplication of code. I've forked the sample project here to demonstrate how it can be done using frames.

customer-frame.xml contains fields of the base entity and a datasource for it:

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.company.entityinheritance.gui.customer.CustomerFrame"
        focusComponent="fieldGroup"
        messagesPack="com.company.entityinheritance.gui.customer">
    <dsContext>
        <datasource id="customerDs"
                    class="com.company.entityinheritance.entity.Customer"
                    view="_local"/>
    </dsContext>
    <layout spacing="true">
        <fieldGroup id="fieldGroup"
                    datasource="customerDs">
            <column width="250px">
                <field id="name"/>
                <field id="email"/>
            </column>
        </fieldGroup>
    </layout>
</window>

In the CustomerFrame controller there is a public method to set an instance to the datasource:

public class CustomerFrame extends AbstractFrame {

    @Inject
    private Datasource<Customer> customerDs;

    public void setCustomer(Customer customer) {
        customerDs.setItem(customer);
    }
}

The Company editor company-edit.xml includes the frame instead of Customer fields:

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.company.entityinheritance.gui.company.CompanyEdit"
        datasource="companyDs"
        focusComponent="customerFrame"
        messagesPack="com.company.entityinheritance.gui.company">
    <dsContext>
        <datasource id="companyDs"
                    class="com.company.entityinheritance.entity.Company"
                    view="_local"/>
    </dsContext>
    <layout expand="windowActions"
            spacing="true">
        <frame id="customerFrame"
               screen="demo$Customer.frame"/>
        <fieldGroup id="fieldGroup"
                    datasource="companyDs">
            <column width="250px">
                <field id="industry"/>
            </column>
        </fieldGroup>
        <frame id="windowActions"
               screen="editWindowActions"/>
    </layout>
</window>

In the Company editor controller, the frame is injected and an edited instance is passed to it:

public class CompanyEdit extends AbstractEditor<Company> {

    @Inject
    private CustomerFrame customerFrame;

    @Override
    protected void postInit() {
        customerFrame.setCustomer(getItem());
    }
}

这篇关于CUBA:实体继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆