3.5.5.2.4. CreateAction
CreateAction 是 列表操作 设计用来创建新的实体实例。它能创建新实例并使用新创建的实例打开实体编辑界面。在编辑界面保存了实体实例之后,操作会将其添加至 UI 组件的数据容器。
该操作通过 com.haulmont.cuba.gui.actions.list.CreateAction 类实现,在 XML 中需要使用操作属性 type="create" 定义。可以用 action 元素的 XML 属性定义通用的操作参数,参阅 声明式操作 了解细节。下面我们介绍 CreateAction 类特有的参数。
下列参数可以通过 XML 或 Java 的方式设置:
-  
openMode- 编辑界面的打开模式,要求是OpenMode枚举类型的一个值:NEW_TAB、DIALOG等。默认情况下,CreateAction 用THIS_TAB模式打开编辑界面。 -  
screenId- 编辑界面的字符串 id。CreateAction 默认会使用带有@PrimaryEditorScreen注解的界面,或<entity_name>.edit格式的界面标识符,比如,demo_Customer.edit。 -  
screenClass- 编辑界面控制器的 Java 类。比screenId有更高的优先级。 
示例,需要以对话框方式打开一个特定的编辑界面,可以在 XML 中这样配置操作:
<action id="create" type="create">
    <properties>
        <property name="openMode" value="DIALOG"/>
        <property name="screenClass" value="com.company.sales.web.customer.CustomerEdit"/>
    </properties>
</action> 
  或者,可以在界面控制器注入该操作,然后用 setter 配置:
@Named("customersTable.create")
private CreateAction customersTableCreate;
@Subscribe
public void onInit(InitEvent event) {
    customersTableCreate.setOpenMode(OpenMode.DIALOG);
    customersTableCreate.setScreenClass(CustomerEdit.class);
} 
  现在我们看看那些只能用 Java 代码配置的参数。如果要为这些参数生成带正确注解的方法桩代码,可以用 Studio 中 Component Inspector 工具窗口的 Handlers 标签页功能。
-  
screenOptionsSupplier- 返回ScreenOptions对象的处理器,返回值可以传递给打开的编辑界面。示例:@Install(to = "customersTable.create", subject = "screenOptionsSupplier") protected ScreenOptions customersTableCreateScreenOptionsSupplier() { return new MapScreenOptions(ParamsMap.of("someParameter", 10)); }返回的
ScreenOptions对象可以通过打开界面的InitEvent访问。 -  
screenConfigurer- 接收编辑界面作为参数并能在打开之间初始化界面的处理器。示例:@Install(to = "customersTable.create", subject = "screenConfigurer") protected void customersTableCreateScreenConfigurer(Screen editorScreen) { ((CustomerEdit) editorScreen).setSomeParameter(10); }注意,界面 configurer 会在界面已经初始化但是还未显示时生效,即在界面的
InitEvent和AfterInitEvent事件之后,但是在BeforeShowEvent之前。 -  
newEntitySupplier- 返回一个展示在编辑界面实体新实例的处理器。示例:@Install(to = "customersTable.create", subject = "newEntitySupplier") protected Customer customersTableCreateNewEntitySupplier() { Customer customer = metadata.create(Customer.class); customer.setName("a customer"); return customer; } -  
initializer- 接收新实体实例作为参数并能在展示到编辑界面之前对其做初始化的处理器。示例:@Install(to = "customersTable.create", subject = "initializer") protected void customersTableCreateInitializer(Customer entity) { entity.setName("a customer"); } -  
afterCommitHandler- 当实体实例在编辑界面提交之后会被调用的处理器。接收创建的实体作为参数。示例:@Install(to = "customersTable.create", subject = "afterCommitHandler") protected void customersTableCreateAfterCommitHandler(Customer entity) { System.out.println("Created " + entity); } -  
afterCloseHandler- 在编辑界面关闭后调用的处理器。AfterCloseEvent事件会传递给该处理器。示例:@Install(to = "customersTable.create", subject = "afterCloseHandler") protected void customersTableCreateAfterCloseHandler(AfterCloseEvent event) { if (event.closedWith(StandardOutcome.COMMIT)) { System.out.println("Committed"); } } 
如果需要在该操作执行前做一些检查或者与用户做一些交互,可以订阅操作的 ActionPerformedEvent 事件并按需调用操作的 execute() 方法。操作会使用你为它定义的所有参数进行调用。下面的例子中,我们在执行操作前展示了一个确认对话框:
@Named("customersTable.create")
private CreateAction customersTableCreate;
@Subscribe("customersTable.create")
public void onCustomersTableCreate(Action.ActionPerformedEvent event) {
    dialogs.createOptionDialog()
            .withCaption("Please confirm")
            .withMessage("Do you really want to create new customer?")
            .withActions(
                    new DialogAction(DialogAction.Type.YES)
                            .withHandler(e -> customersTableCreate.execute()), // execute action
                    new DialogAction(DialogAction.Type.NO)
            )
            .show();
} 
  另外,还可以先订阅 ActionPerformedEvent,但是不调用操作的 execute() 方法,而是使用 ScreenBuilders API 直接打开编辑界面。此时,会忽略所有的操作参数和行为,只能用其通用参数,比如 caption, icon 等。示例:
@Inject
private ScreenBuilders screenBuilders;
@Subscribe("customersTable.create")
public void onCustomersTableCreate(Action.ActionPerformedEvent event) {
    screenBuilders.editor(customersTable)
            .newEntity()
            .withOpenMode(OpenMode.DIALOG)
            .withScreenClass(CustomerEdit.class)
            .withAfterCloseListener(afterScreenCloseEvent -> {
                if (afterScreenCloseEvent.closedWith(StandardOutcome.COMMIT)) {
                    Customer committedCustomer = (afterScreenCloseEvent.getScreen()).getEditedEntity();
                    System.out.println("Created " + committedCustomer);
                }
            })
            .build()
            .show();
}