1

我创建了一个包装 UI5 MultiComboBox Web 组件的 Vaadin Flow v22 组件:

@Tag("ui5-multi-combobox")
@NpmPackage(value = "@ui5/webcomponents", version = "^1.1.2")
@JsModule("@ui5/webcomponents/dist/MultiComboBox.js")
@JsModule("@ui5/webcomponents/dist/features/InputElementsFormSupport.js")
public class Ui5MultiComboBox extends Component implements HasComponents, HasLabel, HasSize {
    …
    public void setPlaceholder(String placeholder) {
        this.getElement().setProperty("placeholder", placeholder);
    }
    …
    @DomEvent("selection-change")
    public static class SelectionChangeEvent extends ComponentEvent<Ui5MultiComboBox> {
        public SelectionChangeEvent(Ui5MultiComboBox source, boolean fromClient,
                @EventData("element.placeholder") String placeholder,
                @EventData("event.bubbles") boolean bubbles,
                @EventData("event.items") JsonArray itemsa) {
            super(source, fromClient);
            LOGGER.info("Ui5MultiComboBoxSelectionChangeEvent: placeholder=" + placeholder);
            LOGGER.info("Ui5MultiComboBoxSelectionChangeEvent: bubbles=" + bubbles);
            LOGGER.info("Ui5MultiComboBoxSelectionChangeEvent: itemsa=" + itemsa);
        }
    }
    …
    public Registration addSelectionChangeListener(ComponentEventListener<SelectionChangeEvent> listener) {
        return addListener(SelectionChangeEvent.class, listener);
    }
}

然后我在我的 Vaadin 视图中使用 Vaadin 组件:

…
Ui5MultiComboBox multiCombo1 = new Ui5MultiComboBox();
multiCombo1.setPlaceholder("Enter or pick items");
multiCombo1.addSelectionChangeListener(e -> {
    LOGGER.info("View: Selection Changed Listener ...");
});

getContent().add(multiCombo1);

// add items:
for (ItemData d : data) {
    Ui5MultiComboBoxItem multiComboItem = new Ui5MultiComboBoxItem();
    multiComboItem.setText(d.text);
    multiComboItem.setSelected(d.selected);

    multiCombo1.add(multiComboItem);
}

我运行我的应用程序(在 Crome 中),它按预期呈现。当我删除其中一个时Ui5MultiComboBoxItem,我的 Listener 会按预期触发。

问题是侦听器无法访问 @EventData("event.items") JsonArray itemsa。

控制台显示该itemsa变量为 null,而访问更简单的 @EventData (如“element.placeholder”或“event.bubbles”)完美工作:

Ui5MultiComboBoxSelectionChangeEvent: placeholder=Enter or pick items
Ui5MultiComboBoxSelectionChangeEvent: bubbles=true
Ui5MultiComboBoxSelectionChangeEvent: itemsa=null
View: Selection Changed Listener ...

我也用过:

@EventData("event.detail") JsonArray itemsa
@EventData("event.detail.items") JsonArray itemsa
@EventData("event.detail") JsonObject itemsa
@EventData("event.detail.items") JsonObject itemsa
@EventData("event.detail") String itemsa
@EventData("event.detail.items") String itemsa
@EventData("event.detail") Object itemsa
@EventData("event.detail.items") Object itemsa

但所有这些都会在 Chrome 控制台中引发错误:

(String) : Message JsonObject contained a dom node reference which should not be sent to the server and can cause a cyclic dependecy.

" " 中的错字dependecy可能会提示是谁发出了该错误消息。

这是 UI5 Web 组件说明:MultiComboBox

任何帮助都非常感谢!

4

1 回答 1

0

您需要详细了解您正在集成的 Web 组件是如何实现这些细节的。我在这里以我自己的一个项目为例。所以假设我有 web 组件tab-sheet,我在其中触发自定义甚至调用tab-changed.我需要在事件中将一些元数据传递到服务器端,所以我details用几个属性组成 JSON 对象。

  selectedChanged(e: CustomEvent) {
    const page = e.detail.value;
    const tab = this.getTab(page);
    this._doSelectTab(page);
    const details : JSON = <JSON><unknown>{
      "index": page,
      "caption": this.getTabCaption(tab),
      "tab": tab
    }
    const event = new CustomEvent('tab-changed', {
        detail: details,
        composed: true,
        cancelable: true,
        bubbles: true       
    });
    this.dispatchEvent(event);
  }

组件的完整实现在这里:https ://github.com/TatuLund/TabSheet/blob/master/src/main/resources/META-INF/resources/frontend/tab-sheet.ts

现在,我想在作为组件的服务器端表示的 Java 类上观察此事件。

为此,我@DomEvent在事件类的构造函数中使用它来解密 JSON @EventData("event.detail"),它现在包含我编写的 JSON 对象。

    @DomEvent("tab-changed")
    public static class TabChangedEvent<R extends TabSheet> extends ComponentEvent<TabSheet> {
        private int index;
        private TabSheet source;
        private String caption;
        private String tab;

        public TabChangedEvent(TabSheet source, boolean fromClient, @EventData("event.detail") JsonObject details) {
            super(source, fromClient);
            this.index = (int) details.getNumber("index");
            this.tab = details.getString("tab");
            this.caption = details.getString("caption");
            this.source = source;
        }
    ...
    }

完整代码在这里:https ://github.com/TatuLund/TabSheet/blob/master/src/main/java/org/vaadin/addons/tatu/TabSheet.java

于 2022-02-09T06:25:26.260 回答