Vaadin @DebouceSettings 示例

Vaadin @DebouceSettings example

我尝试编写一个 TexField,在每次按键时触发一个事件(搜索)。

但是事件应该有一个去抖动选项,这样它只在给定的时间后触发,而无需按键。

我遵循这个文档:https://vaadin.com/docs/v13/flow/creating-components/tutorial-component-events.html

但我很难理解如何将 @DebouceEvent 添加到我的 TextField...

事件:

@DomEvent(value = "input",
          debounce = @DebounceSettings(
              timeout = 250,
              phases = DebouncePhase.TRAILING))
public class InputEvent extends ComponentEvent<TextField> {
    private String value;

    public InputEvent(TextField source, boolean fromClient,
            @EventData("element.value") String value) {
        super(source, fromClient);
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

文本字段:

 TextField searchField= new TextField("my search");

我试过了:

searchField.addInputListener(new InputEvent(searchField, true, "input"));

错误:

Error:(41, 38) java: incompatible types: nc.unc.importparcoursup.view.AdmisDetailView.InputEvent cannot be converted to com.vaadin.flow.component.ComponentEventListener<com.vaadin.flow.component.InputEvent>

我认为您在方法中增加了不必要的复杂性。 TextField 具有 setValueChangeMode 和 setValueChangeTimeOut 方法,可用于将 TextField 配置为按照您明显尝试的方式运行。参见 https://vaadin.com/api/platform/14.0.0.rc7/com/vaadin/flow/component/textfield/TextField.html#setValueChangeTimeout-int-

这条线有两个问题

searchField.addInputListener(new InputEvent(searchField, true, "input"));
  1. addInputListener 不适用于您的活动,只是恰好名称相似
  2. 参数应该是一个监听器,而不是一个事件

解决方案

为了添加您的自定义事件,您需要扩展 TextField class(或构建您自己的扩展 Component 的文本字段)。

我称我的领域为SearchField

public class SearchField extends TextField {

    public SearchField(String caption) {
        super(caption);
    }
}

接下来,我们可以创建事件class。我将名称更改为 SearchEvent 以避免混淆。我还增加了延迟,以便更容易测试它是否有效。最后,这里它扩展了 ComponentEvent<TextField>,但它也可以扩展 ComponentEvent<SearchField>.

@DomEvent(value = "input",
        debounce = @DebounceSettings(
                timeout = 1000,
                phases = DebouncePhase.TRAILING))
public class SearchEvent extends ComponentEvent<TextField> {
    private String value;

    public SearchEvent(TextField source, boolean fromClient,
                       @EventData("element.value") String value) {
        super(source, fromClient);
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

现在我们可以创建一个方法来在 SearchField class.

中添加此事件类型的侦听器
public class SearchField extends TextField {

    ...

    public Registration addSearchListener(ComponentEventListener<SearchEvent> listener) {
        return addListener(SearchEvent.class, listener);
    }
}

终于可以试一试了

@Route
public class SearchView extends VerticalLayout {

    public SearchView() {
        SearchField searchField = new SearchField("Search");
        searchField.addSearchListener(event -> {
            Notification.show("You searched for [" + event.getValue() + "]");
        });
        add(searchField);
    }
}

备注

在 Vaadin 14 中,目前处于预发布阶段,应该很快就会发布,你可以简单地做

TextField textField = new TextField();
textField.setValueChangeMode(ValueChangeMode.LAZY);