Docs

Documentation versions (currently viewingVaadin 24)
Documentation translations (currently viewingChinese)

此页面是对官方文档(http://vaadin.com/docs)的机器翻译版本,可能包含错误、不准确或误述。Vaadin 对译文的准确性、可靠性或及时性不作任何保证或声明。

Custom Field

使用 Custom Field 将多个组件包装为单个字段。

Custom Field 是一个用于将多个组件包装为单个字段的组件。 它提供了标签、辅助信息、验证和数据绑定等标准输入字段功能。您可以使用它来创建自定义的输入组件。

Open in a
new tab
Source code
DateRangePicker.java
CustomFieldBasic.java
LocalDateRange.java
Appointment.java
custom-field-basic.tsx
custom-field-basic.ts

基础用法

Custom Field 已针对以下组件的封装进行了优化:

它还可以用于为自身不带有标签、辅助信息等字段功能的组件(如List Box)提供这些特性。

值类型与格式

Custom Field 值的类型、格式及传播方式在 Java 与 Lit 和 React 中有所不同。以下两个部分解释了如何根据您偏好的编程语言或方法,配置这些内容。

Java

Custom Field 是一个泛型类,可以接受任意类型作为值类型。值类型支持任意类型:字符串(String)、列表(List)、bean 或其他。

指定类型后,您需要建立 Custom Field 的值如何传播到子组件,以及子组件的值如何反过来更新 Custom Field 的值。值传播严重依赖于 Custom Field 所包含的组件、结构以及组件类型。因此,并未提供默认实现,而由 Custom Field 提供两个必须手动实现的方法: generateModelValuesetPresentationValue

generateModelValue 方法负责定义如何从子组件值生成 Custom Field 值。当子组件在客户端触发 DOM 更改事件时,Custom Field 会执行该方法以更新自身值。在此方法中,通常需要收集所有子组件的值,并基于这些值返回一个单一的 Custom Field 类型对象。

setPresentationValue 方法接收一个 Custom Field 值,并定义如何将该值分发至子组件。当 Custom Field 的值在服务端程序变动时,它会触发此方法以更新子组件值。在此方法中,通常需要将给定的值拆分,并分别设置到各个子组件。

以下示例演示了如何设置值传播,使用了一个 bean 作为值类型:

Source code
Java
class Phone {
    private final String code;
    private final String number;

    public Phone(String code, String number) {
        this.code = code;
        this.number = number;
    }

    public String getCode() {
        return code;
    }

    public String getNumber() {
        return number;
    }
}

class PhoneField extends CustomField<Phone> {
    private final Select code = new Select();
    private final TextField number = new TextField();

    public PhoneField() {
        ...

        add(code, number);
    }

    @Override
    protected Phone generateModelValue() {
        return new Phone(code.getValue(), number.getValue());
    }

    @Override
    protected void setPresentationValue(Phone value) {
        code.setValue(value.getCode());
        number.setValue(value.getNumber());
    }
}

Lit 和 React

Custom Field 只支持字符串值。然而,它提供了对值的格式进行控制的 parser 和 formatter。parser 和 formatter 定义了 Custom Field 的值如何拆分至子组件以及如何由子组件值合并形成整体值。当子组件触发更改事件或者 Custom Field 值被程序修改时, Custom Field 会根据 parser 或 formatter 执行相应的值传播操作。

Parser

当 Custom Field 值被程序修改时,Custom Field 会将该值传递给 parser。parser 应将其转换为子组件值的数组,这些值的顺序应与它们在 DOM 中的呈现顺序一致。Custom Field 聚合这些值,并使用子组件的 value 属性分配它们。

默认的 parser 使用 \t 字符将值拆分为各个子组件的值。

Formatter

当 Custom Field 检测到子组件触发的更改事件时,它收集所有子组件的 value 属性,并按照子组件在 DOM 中的顺序作为一个数组传递给 formatter。formatter 应该将这个数组转换为单个字符串值,Custom Field 随后使用 formatter 返回的字符串更新自身值。

默认的 formatter 使用 \t 字符连接各个子组件的值。

您可以定义自己的 parser 和 formatter 来自定义值的格式,如下所示:

Source code
tsx
function Example() {
  return (
    // Phone Custom Field
    <CustomField
      formatValue={([code, number]: unknown[]) => (code && number ? [code, number].join('|') : '')}
      parseValue={(value: string) => (value ? value.split('|') : ['', ''])}
    >
      {/* Country code */}
      <Select />

      {/* Phone number */}
      <TextField />
    </CustomField>
  );
}
tsx
ts
ts

原生输入字段

Custom Field 同样可以配合原生 HTML 元素使用。当用于 Custom Field 内部的组件没有外部边距时,可以使用 whitespace 变体,以弥补标签与组件之间缺失的空间。

尺寸变体

可以使用 small 主题变体缩小 Custom Field 的标签、辅助信息及错误信息。Custom Field 不会将其主题变体自动传播至其内部组件,每个内部组件的主题变体都需要单独设置。

CB7FDF39-7653-4DF0-A0C0-9C2A2EE7EDBA