3.5.5.2.8. LookupAction

LookupAction 是 选取器控件操作 设计用来从查找界面选取实体实例并设置给选取器。

该操作通过 com.haulmont.cuba.gui.actions.picker.LookupAction 类实现,在 XML 中需要使用操作属性 type="picker_lookup" 定义。可以用 action 元素的 XML 属性定义通用的操作参数,参阅 声明式操作 了解细节。下面我们介绍 LookupAction 类特有的参数。

下列参数可以通过 XML 或 Java 的方式设置:

  • openMode - 查找界面的打开模式,要求是 OpenMode 枚举类型的一个值:NEW_TABDIALOG 等。默认情况下,LookupAction 用 THIS_TAB 模式打开查找界面。

  • screenId - 查找界面的字符串 id。LookupAction 默认会使用带有 @PrimaryLookupScreen 注解的界面,或 <entity_name>.lookup<entity_name>.browse 格式的界面标识符,比如, demo_Customer.browse

  • screenClass - 查找界面控制器的 Java 类。比 screenId 有更高的优先级。

示例,需要以对话框方式打开一个特定的查找界面,可以在 XML 中这样配置操作:

  1. <action id="lookup" type="picker_lookup">
  2. <properties>
  3. <property name="openMode" value="DIALOG"/>
  4. <property name="screenClass" value="com.company.sales.web.customer.CustomerBrowse"/>
  5. </properties>
  6. </action>

或者,可以在界面控制器注入该操作,然后用 setter 配置:

  1. @Named("customerField.lookup")
  2. private LookupAction customerFieldLookup;
  3. @Subscribe
  4. public void onInit(InitEvent event) {
  5. customerFieldLookup.setOpenMode(OpenMode.DIALOG);
  6. customerFieldLookup.setScreenClass(CustomerBrowse.class);
  7. }

现在我们看看那些只能用 Java 代码配置的参数。如果要为这些参数生成带正确注解的方法桩代码,可以用 Studio 中 Component Inspector 工具窗口的 Handlers 标签页功能。

  • screenOptionsSupplier - 返回 ScreenOptions 对象的处理器,返回值可以传递给打开的查找界面。示例:

    1. @Install(to = "customerField.lookup", subject = "screenOptionsSupplier")
    2. private ScreenOptions customerFieldLookupScreenOptionsSupplier() {
    3. return new MapScreenOptions(ParamsMap.of("someParameter", 10));
    4. }

    返回的 ScreenOptions 对象可以通过打开界面的 InitEvent 访问。

  • screenConfigurer - 接收查找界面作为参数并能在打开之间初始化界面的处理器。示例:

    1. @Install(to = "customerField.lookup", subject = "screenConfigurer")
    2. private void customerFieldLookupScreenConfigurer(Screen screen) {
    3. ((CustomerBrowse) screen).setSomeParameter(10);
    4. }

    注意,界面 configurer 会在界面已经初始化但是还未显示时生效,即在界面的 InitEventAfterInitEvent 事件之后,但是在 BeforeShowEvent 之前。

  • selectValidator - 当用户在查找界面点击 Select 时调用的一个处理器。接收包含选中条目集合的对象作为参数。集合的第一个条目会设置给该选取器。可以用这个处理器检查选中的条目是否满足某些条件。处理器必须返回 true 才能继续关闭查找界面。示例:

    1. @Install(to = "customerField.lookup", subject = "selectValidator")
    2. private boolean customerFieldLookupSelectValidator(LookupScreen.ValidationContext<Customer> validationContext) {
    3. boolean valid = validationContext.getSelectedItems().size() == 1;
    4. if (!valid) {
    5. notifications.create().withCaption("Select a single customer").show();
    6. }
    7. return valid;
    8. }
  • transformation - 在查找界面选择实体并验证之后调用的处理器。接收选中的实体集合作为参数。集合的第一个条目会设置给该选取器。可以用这个处理器对选中的实体做一些处理,然后再传递给选取器。示例:

    1. @Install(to = "customerField.lookup", subject = "transformation")
    2. private Collection<Customer> customerFieldLookupTransformation(Collection<Customer> collection) {
    3. return reloadCustomers(collection);
    4. }
  • afterCloseHandler - 在查找界面关闭后调用的处理器。AfterCloseEvent 事件会传递给该处理器。示例:

    1. @Install(to = "customerField.lookup", subject = "afterCloseHandler")
    2. private void customerFieldLookupAfterCloseHandler(AfterCloseEvent event) {
    3. if (event.closedWith(StandardOutcome.SELECT)) {
    4. System.out.println("Selected");
    5. }
    6. }

如果需要在该操作执行前做一些检查或者与用户做一些交互,可以订阅操作的 ActionPerformedEvent 事件并按需调用操作的 execute() 方法。操作会使用你为它定义的所有参数进行调用。下面的例子中,我们在执行操作前展示了一个确认对话框:

  1. @Named("customerField.lookup")
  2. private LookupAction customerFieldLookup;
  3. @Subscribe("customerField.lookup")
  4. public void onCustomerFieldLookup(Action.ActionPerformedEvent event) {
  5. dialogs.createOptionDialog()
  6. .withCaption("Please confirm")
  7. .withMessage("Do you really want to select a customer?")
  8. .withActions(
  9. new DialogAction(DialogAction.Type.YES)
  10. .withHandler(e -> customerFieldLookup.execute()), // execute action
  11. new DialogAction(DialogAction.Type.NO)
  12. )
  13. .show();
  14. }

另外,还可以先订阅 ActionPerformedEvent,但是不调用操作的 execute() 方法,而是使用 ScreenBuilders API 直接打开查找界面。此时,会忽略所有的操作参数和行为,只能用其通用参数,比如 caption, icon 等。示例:

  1. @Inject
  2. private ScreenBuilders screenBuilders;
  3. @Inject
  4. private LookupPickerField<Customer> customerField;
  5. @Subscribe("customerField.lookup")
  6. public void onCustomerFieldLookup(Action.ActionPerformedEvent event) {
  7. screenBuilders.lookup(customerField)
  8. .withOpenMode(OpenMode.DIALOG)
  9. .withScreenClass(CustomerBrowse.class)
  10. .withSelectValidator(customerValidationContext -> {
  11. boolean valid = customerValidationContext.getSelectedItems().size() == 1;
  12. if (!valid) {
  13. notifications.create().withCaption("Select a single customer").show();
  14. }
  15. return valid;
  16. })
  17. .build()
  18. .show();
  19. }