在 Flow Builder 中自定义操作和屏幕组件 UI

开发一个自定义属性编辑器,当管理员在 Flow Builder 中配置自定义屏幕组件或可调用操作时,该编辑器可为其提供简化的 UI。自定义属性编辑器是一个 Lightning Web 组件,它提供用于输入输入值的自定义 UI。

将自定义属性编辑器与标准属性编辑器进行比较

如果没有自定义属性编辑器,当管理员在 Flow Builder 中配置自定义流屏幕组件或可调用操作时,UI 由组件输入值的文本框或组合框组成。自定义属性编辑器的 UI 可以由任何输入组件组成,并且可以使用自定义样式。此示例显示了一个没有自定义属性编辑器的自定义流屏幕组件。该组件显示将数据传递到流中的输入属性的文本框和组合框。

相反,请创建一个自定义属性编辑器,为管理员提供简化的体验。此示例显示了一个自定义流屏幕组件,该组件具有自定义属性编辑器,该编辑器使用自定义标签和滑块组件作为输入值。

示例:可调用操作的自定义属性编辑器

此示例创建一个可调用操作及其自定义属性编辑器。在 Flow Builder 中,管理员为“发送 HTML 电子邮件”可调用操作设置输入值。当用户运行流时,可调用操作会发送电子邮件。

此 Apex 类文件定义了可作为可调用操作运行的方法及其输入变量。注释标识可作为可调用操作运行的可调用方法。注释标识可调用方法使用的变量。sendEmails@InvocableMethod@InputVariable

可调用方法在修饰符中注册自定义属性编辑器。除非组织具有自定义命名空间,否则命名空间。如果组织具有自定义命名空间,请使用该命名空间注册自定义属性编辑器。在此示例中,自定义属性编辑器的名称为 。configurationEditorcc-html-email-editor

// HtmlEmailAction.cls
global class HtmlEmailAction {
    global class EmailActionRequest {
        @InvocableVariable
        global String senderName;

        @InvocableVariable
        global String replyToEmail;

        @InvocableVariable
        global String recipientName;

        @InvocableVariable
        global String sendToEmail;

        @InvocableVariable
        global String subject;

        @InvocableVariable
        global String htmlBody;
    }

    global class EmailActionResult {
        @InvocableVariable
        global Boolean isSuccess;

        @InvocableVariable
        global String errorMessage;
    }

    @InvocableMethod(label='Send HTML Email' configurationEditor='c-html-email-editor')
    global static List<EmailActionResult> sendEmails(List<EmailActionRequest> requests) {
        List<EmailActionResult> results = new List<EmailActionResult>();

        for(EmailActionRequest request : requests){
            results.add(sendEmail(request));
        }

        return results;
    }

    public static EmailActionResult sendEmail(EmailActionRequest request) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        String[] sendToEmail = new String[]{ request.sendToEmail };
        mail.setToAddresses(sendToEmail);
        mail.setSenderDisplayName(request.senderName);
        mail.setReplyTo(request.replyToEmail);
        mail.setSubject(request.subject);
        mail.setHtmlBody(request.htmlBody);
        mail.setOptOutPolicy('FILTER');

        Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage>();
        messages.add(mail);

        Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
        EmailActionResult emailActionResult = new EmailActionResult();

        for(Messaging.SendEmailResult result :results) {
            if(result.IsSuccess()) {
                emailActionResult.isSuccess = true;
            } else {
                emailActionResult.isSuccess = false;
                Messaging.SendEmailError[] errors = result.getErrors();
                if (errors.size() > 0 ){
                    emailActionResult.errorMessage = errors[0].getMessage();
                }
            }
        }

        return emailActionResult;
    }
}

这些 HTML、CSS、JavaScript 和配置文件定义操作的自定义属性编辑器。

HTML 模板定义 Flow Builder 中自定义属性编辑器的 UI。

<!--htmlEmailEditor.html-->
<template>
  <div class="slds-m-bottom_x-small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">
      Sender Information
    </h2>

    <div class="slds-p-around_xx-small lgc-bg">
      <lightning-input
        type="text"
        label="Sender Name"
        placeholder="Enter sender name here..."
        value={senderName}
        onchange={handleSenderNameChange}
      >
      </lightning-input>

      <lightning-input
        type="email"
        label="Reply-To Email Address"
        placeholder="Enter reply-to email address here..."
        value={replyToEmail}
        onchange={handleReplyToEmailChange}
      >
      </lightning-input>
    </div>
  </div>

  <div class="slds-m-bottom_x-small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">
      Recipient Information
    </h2>

    <div class="slds-p-around_xx-small lgc-bg">
      <lightning-input
        type="text"
        label="Recipient Name"
        placeholder="Enter recipient name here..."
        value={recipientName}
        onchange={handleRecipientNameChange}
      >
      </lightning-input>

      <lightning-input
        type="email"
        label="Send-To Email Address"
        placeholder="Enter send-to email address here..."
        value={sendToEmail}
        onchange={handleSendToEmailChange}
        required
      >
      </lightning-input>
    </div>
  </div>

  <div class="slds-m-top_small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">Subject and Body</h2>

    <div class="slds-p-around_xx-small lgc-bg">
      <lightning-input
        type="text"
        label="Subject"
        placeholder="Enter subject here..."
        value={subject}
        onchange={handleSubjectChange}
      >
      </lightning-input>

      <div class="row">
        <lightning-textarea
          name="body"
          label="HTML Body"
          placeholder="Enter html body here..."
          value={htmlBody}
          onchange={handleHtmlBodyChange}
        >
        </lightning-textarea>
      </div>
    </div>
  </div>
</template>

此示例显示自定义属性编辑器 UI。

初始化自定义属性编辑器后,JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中更改值时,自定义属性编辑器会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// htmlEmailEditor.js
import { LightningElement, api } from "lwc";
export default class HtmlEmailEditor extends LightningElement {
  @api
  inputVariables;

  get senderName() {
    const param = this.inputVariables.find(({ name }) => name === "senderName");
    return param && param.value;
  }

  get replyToEmail() {
    const param = this.inputVariables.find(({ name }) => name === "replyToEmail");
    return param && param.value;
  }

  get recipientName() {
    const param = this.inputVariables.find(({ name }) => name === "recipientName");
    return param && param.value;
  }

  get sendToEmail() {
    const param = this.inputVariables.find(({ name }) => name === "sendToEmail");
    return param && param.value;
  }

  get subject() {
    const param = this.inputVariables.find(({ name }) => name === "subject");
    return param && param.value;
  }

  get htmlBody() {
    const param = this.inputVariables.find(({ name }) => name === "htmlBody");
    return param && param.value;
  }

  @api validate() {
    const validity = [];
    if (
      !this.isValidEmailAddress(this.sendToEmail) ||
      !this.isValidEmailAddress(this.replyToEmail)
    ) {
      validity.push({
        key: "SendToAddress",
        errorString: "You have entered an invalid email format.",
      });
    }
    return validity;
  }

  isValidEmailAddress(email) {
    const emailRegex = /^\w+([\.-]?\w+)+@\w+([\.:]?\w+)+(\.[a-zA-Z0-9]{2,3})+$/;
    return emailRegex.test(email);
  }

  handleSenderNameChange(event) {
    this.handleChange(event, "senderName");
  }

  handleReplyToEmailChange(event) {
    this.handleChange(event, "replyToEmail");
  }

  handleRecipientNameChange(event) {
    this.handleChange(event, "recipientName");
  }

  handleSendToEmailChange(event) {
    this.handleChange(event, "sendToEmail");
  }

  handleSubjectChange(event) {
    this.handleChange(event, "subject");
  }

  handleHtmlBodyChange(event) {
    this.handleChange(event, "htmlBody");
  }

  handleChange(event, name) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name,
          newValue,
          newValueDataType: "String",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 和 接口。inputVariablesvalidate

初始化自定义属性编辑器后,从 Flow Builder 接收可调用操作中输入变量的值。inputVariables

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[
  {
    name: "senderName",
    value: "Test Inc",
    valueDataType: "String",
  },
];

方法(如 和 )获取每个输入变量,以便在自定义属性编辑器中使用。getget senderName()get replyToEmail()value

当管理员在 Flow Builder 的屏幕编辑器 UI 中单击“完成”时,Flow Builder 会在自定义属性编辑器中评估函数。如果函数返回 和 数据结构,则屏幕编辑器会显示错误数,并阻止管理员在屏幕编辑器中保存更改。validatekeyerrorString

注意

Flow Builder 仅显示错误数。若要显示错误字符串,请在方法中编写代码。有关更多信息,请参见自定义属性编辑器 JavaScript 接口。validate

当管理员在自定义属性编辑器中输入输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleChangeconfiguration_editor_input_value_changed

下面是 的配置文件。htmlEmailEditor

<!--htmlEmailEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>49.0</apiVersion>
    <!--isExposed can be true or false-->
    <isExposed>true</isExposed>
</LightningComponentBundle>

示例:屏幕组件的自定义属性编辑器

此示例为显示卷的自定义流屏幕组件创建自定义属性编辑器。管理员使用卷组件的自定义属性编辑器中的滑块设置卷。当用户运行流程时,流程屏幕会显示管理员设置的音量级别。

以下 HTML、JavaScript 和配置文件定义自定义流屏幕组件。volume

<!--volume.html-->
<template>
  <div>
    <h1 class="slds-text-heading_medium">Volume</h1>
  </div>

  <div class="slds-p-top_xxx-small">
    <p>
      Your selected volume is:
      <lightning-formatted-number value={volume}></lightning-formatted-number>
    </p>
  </div>
</template>

JavaScript 类定义一个公共属性。volume

// volume.js
import { LightningElement, api } from "lwc";

export default class Volume extends LightningElement {
  @api volume;
}

要在 Flow Builder 中公开公共属性,请在配置文件中定义它:。该特性确定属性是否可以接收来自流的输入。本示例中使用的默认值为 。若要使属性仅可用于输入或输出,请将该特性设置为 或 。volume<property name="volume" type="Integer"/>roleinputAndOutputroleinputOnlyoutputOnly

在配置文件中,使用属性注册自定义属性编辑器:。除非组织具有自定义命名空间,否则请使用命名空间。如果组织具有自定义命名空间,请使用该命名空间。configurationEditor<targetConfig targets="lightning__FlowScreen" configurationEditor="c-volume-editor">c

<!-- volume.js-meta.xml-->
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>49.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <masterLabel>Volume</masterLabel>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen" configurationEditor="c-volume-editor">
      <property name="volume" type="Integer"/>
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

以下 HTML、JavaScript 和配置文件定义组件的自定义属性编辑器。volume

自定义属性编辑器的 HTML 模板定义 UI,该 UI 使用滑块基础 Lightning Web 组件。

<!--volumeEditor.html-->
<template>
  <div class="slds-p-around_xx-small">
    <lightning-slider label="Volume" step="10" value={volume} onchange={handleChange}>
    </lightning-slider>
  </div>
</template>

初始化自定义属性编辑器时,其 JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中进行更新时,它会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// volumeEditor.js
import { LightningElement, api } from "lwc";

export default class VolumeEditor extends LightningElement {
  _inputVariables = [];

  @api
  get inputVariables() {
    return this._inputVariables;
  }

  // Set a field with the data that was stored from the flow.
  // This data includes the public volume property of the custom volume
  // component.
  set inputVariables(variables) {
    this._inputVariables = variables || [];
  }

  // Get the value of the volume input variable.
  get volume() {
    const param = this.inputVariables.find(({ name }) => name === "volume");
    return param && param.value;
  }

  @api
  validate() {
    const volumeCmp = this.template.querySelector("lightning-slider");
    const validity = [];
    if (this.volume < 0 || this.volume > 100) {
      volumeCmp.setCustomValidity("The slider range is between 0 and 100.");
      validity.push({
        key: "Slider Range",
        errorString: "The slider range is between 0 and 100.",
      });
    } else {
      volumeCmp.setCustomValidity("");
    }
    volumeCmp.reportValidity();
    return validity;
  }

  handleChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "volume",
          newValue,
          newValueDataType: "Number",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 和 接口。inputVariablesvalidate

此示例定义了 的 getter 和 setter。初始化自定义属性编辑器时,setter 从 Flow Builder 接收屏幕组件中公共属性的值。在此示例中,我们使用将流元数据存储在字段中的约定,但您可以根据需要命名该字段。inputVariablesinputVariables_inputVariables

中的数据结构包括每个输入变量的名称、值和数据类型。_inputVariables

[
  {
    name: "volume",
    value: "10",
    valueDataType: "Number",
  },
];

该方法获取用于卷 UI 的属性。volumevaluevolume

当管理员在 Flow Builder 的屏幕编辑器 UI 中单击“完成”时,Flow Builder 会评估每个自定义属性编辑器中的函数。如果函数返回 和 数据结构,则 Flow Builder 会显示错误数,并阻止管理员在屏幕编辑器中保存更改。validatekeyerrorString

注意

Flow Builder 仅显示错误数。若要显示错误字符串,请编写代码。此示例使用组件的函数显示自定义错误消息。使用 interface 方法。lightning-slidersetCustomValidity()validate

当管理员在自定义属性编辑器中输入 volume 的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleChangeconfiguration_editor_input_value_changed

这是 的配置文件。volumeEditor

<!--volumeEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>49.0</apiVersion>
  <!--isExposed can be true or false-->
  <isExposed>true</isExposed>
</LightningComponentBundle>

示例:可调用操作的通用 SObject 输入

此示例为使用泛型 sObject 输入参数的可调用操作创建自定义属性编辑器。可调用操作是可以添加到流程中的 Apex 方法。在 Flow Builder 中,管理员使用选择列表字段来设置可调用操作的输入参数:记录变量的对象、记录变量和用于存储输出的对象。当用户运行此示例的流时,可调用操作将存储记录集合中的第一条记录。

此 Apex 类文件定义了可作为可调用操作运行的方法及其输入变量。注释标识可以作为可调用操作运行的方法。注释标识可调用方法使用的变量。selectRecord@InvocableMethod@InvocableVariable

可调用方法在修饰符中注册自定义属性编辑器。除非组织具有自定义命名空间,否则命名空间。如果组织具有自定义命名空间,请使用该命名空间注册自定义属性编辑器。在此示例中,自定义属性编辑器的名称为 。configurationEditorcc-select-record-editor

// SelectRecordAction.cls
public with sharing class SelectRecordAction {
    @InvocableMethod(configurationEditor='c-select-record-editor')
    public static List <Results> selectRecord(List<Requests> requestList) {
        List<SObject> inputCollection = requestList[0].inputCollection;
        //Store the first input record for output
        SObject outputMember = inputCollection[0];
        Results response = new Results();
        response.outputMember = outputMember;
        List<Results> responseWrapper= new List<Results>();
        responseWrapper.add(response);
        return responseWrapper;
    }

public class Requests {
    @InvocableVariable(label='Object for Input' description='Records for Input')
    public List<SObject> inputCollection;
    }

public class Results {
    @InvocableVariable(label='Object for Storing Output' description='Records for Output')
    public SObject outputMember;
    }
}

这些 HTML、CSS、JavaScript 和配置文件定义操作的自定义属性编辑器。

HTML 模板定义 Flow Builder 中自定义属性编辑器的 UI。

<!--selectRecordEditor.html-->
<template>
  <lightning-combobox
    name="inputType"
    label="Object for Record Variable"
    value={inputType}
    placeholder="Select object..."
    options={typeOptions}
    onchange={handleInputTypeChange}
  >
  </lightning-combobox>

  <lightning-combobox
    name="outputType"
    label="Object for Storing Output"
    value={outputType}
    placeholder="Select object..."
    options={typeOptions}
    onchange={handleOutputTypeChange}
  >
  </lightning-combobox>

  <lightning-combobox
    name="inputValue"
    label="Record Variable"
    value={inputValue}
    placeholder="Select record variable..."
    options={valueOptions}
    onchange={handleValueChange}
  >
  </lightning-combobox>

  <div class="slds-p-bottom_medium"></div>
</template>

此示例显示自定义属性编辑器 UI。

初始化自定义属性编辑器后,JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中更改值时,自定义属性编辑器会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// selectRecordEditor.js
import { LightningElement, api } from "lwc";

export default class SelectRecordEditor extends LightningElement {
  @api
  inputVariables;

  @api
  genericTypeMappings;

  @api
  builderContext;

  get inputValue() {
    const param = this.inputVariables.find(({ name }) => name === "inputCollection");
    return param && param.value;
  }

  get inputType() {
    const type = this.genericTypeMappings.find(({ typeName }) => typeName === "T__inputCollection");
    return type && type.typeValue;
  }

  get outputType() {
    const type = this.genericTypeMappings.find(({ typeName }) => typeName === "U__outputMember");
    return type && type.typeValue;
  }

  get typeOptions() {
    return [
      { label: "Account", value: "Account" },
      { label: "Case", value: "Case" },
      { label: "Lead", value: "Lead" },
    ];
  }

  get valueOptions() {
    const variables = this.builderContext.variables;
    return variables.map(({ name }) => ({
      label: name,
      value: name,
    }));
  }

  handleInputTypeChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const typeChangedEvent = new CustomEvent(
        "configuration_editor_generic_type_mapping_changed",
        {
          bubbles: true,
          cancelable: false,
          composed: true,
          detail: {
            typeName: "T__inputCollection",
            typeValue: newValue,
          },
        },
      );
      this.dispatchEvent(typeChangedEvent);
    }
  }

  handleOutputTypeChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const typeChangedEvent = new CustomEvent(
        "configuration_editor_generic_type_mapping_changed",
        {
          bubbles: true,
          cancelable: false,
          composed: true,
          detail: {
            typeName: "U__outputMember",
            typeValue: newValue,
          },
        },
      );
      this.dispatchEvent(typeChangedEvent);
    }
  }

  handleValueChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "inputCollection",
          newValue,
          newValueDataType: "reference",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 、 和 接口。inputVariablesbuilderContextgenericTypeMappings

初始化自定义属性编辑器后,从 Flow Builder 接收可调用操作中输入变量的值。inputVariables

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[
  {
    name: "inputType",
    value: "Account",
    valueDataType: "Account",
  },
];

该方法获取每个输入变量的值,以便在自定义属性编辑器中使用。get inputValue()

该接口接收输入变量的值,这些变量是 Flow Builder 中可调用操作中的通用 sObject 数据类型。genericTypeMappings

数据结构包括每个输入的名称和值。必须与使用方法中的注释定义的泛型 sObject 输入的名称匹配,例如 。 在输入名称前面加上,并自动在输出名称前面加上。是通用 sObject 输入的特定值,例如 。typeName@InvocableVariable’T__inputCollection’T__U__typeValueAccount

[
  {
    typeName: "T__inputCollection",
    typeValue: "Account",
  },
];

和方法获取每个输入参数的值,该参数是用于自定义属性编辑器的泛型 sObject 数据类型。get inputType()get outputType()

该方法获取每个对象输入选项的标签和值,以便在自定义属性编辑器中使用。get typeOptions()

该接口提供有关流中元素和资源的数据。builderContext

数据结构包括流中的元素和资源。builderContext

该方法使用变量中的数据作为可调用操作输入参数的自定义属性编辑器上的输入值选项。get valueOptions()

当管理员在自定义属性编辑器中为记录变量的对象输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleInputTypeChangeconfiguration_editor_generic_type_mapping_changed

当管理员在自定义属性编辑器中输入用于存储输出的对象的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleOutputTypeChangeconfiguration_editor_generic_type_mapping_changed

当管理员在自定义属性编辑器中输入“记录变量”的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleValueChangeconfiguration_editor_input_value_changed

下面是 的配置文件。selectRecordEditor

<!--selectRecordEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <!--isExposed can be true or false-->
    <isExposed>true</isExposed>
</LightningComponentBundle>

示例:屏幕组件的通用 SObject 输入

此示例为使用泛型输入值的自定义流屏幕组件创建自定义属性编辑器。管理员使用选择列表字段为记录变量的对象和记录变量设置屏幕组件的输入值。当用户运行此示例的流时,屏幕组件将显示记录集合中的第一条记录。sObject

以下 HTML、JavaScript 和配置文件定义自定义流屏幕组件。displayRecord

<!--displayRecord.html-->
<template>
  <p>Record Name: {inputValue.Name}</p>
</template>

JavaScript 类定义一个公共属性。inputValue

// displayRecord.js
import { LightningElement, api } from "lwc";

export default class DisplayRecord extends LightningElement {
  @api
  inputValue;
}

要在 Flow Builder 中公开公共属性,请在配置文件中定义它。若要将属性定义为泛型数据类型,请定义子标记。子标记扩展泛型数据类型。的属性引用子标记的属性。例如,如果 ,则 .子标记的属性必须位于大括号内。要将属性定义为泛型集合数据类型,请追加 ,例如 。inputValuesObjectpropertyTypesObjecttypeinputValuenamepropertyTypepropertyType name="T"property type="{T}"typepropertysObject[]property type="{T[]}"

该特性确定属性是否可以接收来自流的输入。缺省值为 。若要使属性仅可用于输入或输出,请将该特性设置为 或 。roleinputAndOutputroleinputOnlyoutputOnly

在配置文件中,使用该特性注册自定义属性编辑器。configurationEditor

除非组织具有自定义命名空间,否则请使用命名空间。如果组织具有自定义命名空间,请使用该命名空间。c

<!-- displayRecord.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>50.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <masterLabel>Display Record</masterLabel>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen" configurationEditor="c-display-record-editor">
      <propertyType name="T" extends="SObject" label="Input Type" description="Generic sObject data type used for input sObject properties" />
      <property name="inputValue" type={T} label="input value" role="inputOnly" />
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

以下 HTML、JavaScript 和配置文件定义组件的自定义属性编辑器。displayRecord

自定义属性编辑器的 HTML 模板定义了 UI,该 UI 使用组合框基础 Lightning Web 组件。

<!--displayRecordEditor.html-->
<template>
  <lightning-combobox
    name="inputType"
    label="Object for Record Variable"
    value="{inputType}"
    placeholder="Select object..."
    options="{typeOptions}"
    onchange="{handleInputTypeChange}"
  >
  </lightning-combobox>

  <lightning-combobox
    name="inputValue"
    label="Record Variable"
    value="{inputValue}"
    placeholder="Select record variable..."
    options="{valueOptions}"
    onchange="{handleValueChange}"
  >
  </lightning-combobox>
</template>

初始化自定义属性编辑器时,其 JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中进行更新时,它会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// displayRecordEditor.js
import { LightningElement, api } from 'lwc';

export default class DisplayRecordEditor extends LightningElement {
  @api
  inputVariables;

  @api
  genericTypeMappings;

  @api
  builderContext;

  get inputValue() {
    const param = this.inputVariables.find(({ name }) => name === 'inputValue');
    return param && param.value;
  }

  get inputType() {
    const type = this.genericTypeMappings.find(
      ({ typeName }) => typeName === 'T'
    );
    return type && type.typeValue;
  }

  get typeOptions() {
    return [
      { label: 'Account', value: 'Account' },
      { label: 'Case', value: 'Case' },
      { label: 'Lead', value: 'Lead' },
    ];
  }

  get valueOptions() {
    const variables = this.builderContext.variables;
    return variables.map(({ name }) => ({
      label: name,
      value: name,
    }));
  }

  handleInputTypeChange(event) {
    if (event && event.detail) {
    const newValue = event.detail.value;
    const typeChangedEvent = new CustomEvent(
      'configuration_editor_generic_type_mapping_changed',
      {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          typeName: 'T',
          typeValue: newValue
        },
      }
    );
    this.dispatchEvent(typeChangedEvent);
    }
  }

  handleValueChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent(
        'configuration_editor_input_value_changed',
        {
          bubbles: true,
          cancelable: false,
          composed: true,
          detail: {
            name: 'inputValue',
            newValue,
            newValueDataType: 'reference',
          },
        }
      );
    this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 、 和 接口。inputVariablesbuilderContextgenericTypeMappings

初始化自定义属性编辑器后,从 Flow Builder 接收屏幕组件中公共属性的值。inputVariables

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[
  {
    name: "inputType",
    value: "Account",
    valueDataType: "Account",
  },
];

获取要在自定义属性编辑器中使用的属性的值。get inputValue()inputValue

该接口从 Flow Builder 接收输入变量的值,这些变量是屏幕组件中的泛型数据类型。genericTypeMappingssObject

数据结构包括每个输入的名称和值。是泛型输入的名称;例如。是泛型输入的特定值;例如。typeNamesObject'T'typeValuesObjectAccount

[
  {
    typeName: "T",
    typeValue: "Account",
  },
];

获取要在自定义属性编辑器中使用的属性的数据类型。get inputType()inputValue

该方法获取每个对象输入选项的标签和值,以便在自定义属性编辑器中使用。get typeOptions()

该接口提供有关流中元素和资源的数据。builderContext

{
  actionCalls: [],
  apexPluginCalls: [],
  constants: [],
  formulas: [],
  recordCreates: [],
  recordDeletes: [],
  recordLookups: [],
  recordUpdates: [],
  screens: [],
  stages: [],
  textTemplates: [],
  variables: []
}

该方法使用来自 的数据作为屏幕组件输入的自定义属性编辑器上的输入值选项。get valueOptions()variables

当管理员在自定义属性编辑器中为记录变量的对象输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleInputTypeChangeconfiguration_editor_generic_type_mapping_changed

当管理员在自定义属性编辑器中输入“记录变量”的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleValueChangeconfiguration_editor_input_value_changed

这是 的配置文件。displayRecordEditor

<!--displayRecordEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>50.0</apiVersion>
  <!--isExposed can be true or false-->
  <isExposed>true</isExposed>
</LightningComponentBundle>

示例:可调用操作的 SObject 输入

此示例创建一个自定义属性编辑器组件,该组件以使用 Contact 对象输入参数的可调用操作命名。可调用操作是可以添加到流程中的 Apex 方法。在 Flow Builder 中,管理员使用文本字段来设置可调用操作的联系人输入参数。当用户运行此示例的流时,可调用操作会存储一个新联系人。createContactActionEditor

此 Apex 类文件定义了可作为可调用操作运行的方法及其输入变量。注释标识可以作为可调用操作运行的方法。注释标识可调用方法使用的变量。createContact@InvocableMethod@InvocableVariable

可调用方法在修饰符中注册自定义属性编辑器组件。除非组织具有自定义命名空间,否则组件命名空间。如果组织具有自定义命名空间,请使用该命名空间注册自定义属性编辑器组件。在此示例中,组件的名称为 。configurationEditorcc-create-contact-action-editor

//CreateContactAction.cls
global class CreateContactAction {
    global class CreateContactRequest {

        @InvocableVariable
        global Contact contact;
    }

    global class CreateContactResult {
        @InvocableVariable
        global Boolean isSuccess;

        @InvocableVariable
        global String errorMessage;

        @InvocableVariable
        global String contactId;
   }

    @InvocableMethod(label='Create Contact' configurationEditor='c-create-contact-action-editor')
    global static List<CreateContactResult> createContact(List<CreateContactRequest> requests) {
        List<CreateContactResult> results = new List<CreateContactResult>();
            for(CreateContactRequest request : requests){
        results.add(insertContact(request));
        }
        return results;
    }

    public static CreateContactResult insertContact(CreateContactRequest request) {
        List<Contact> contactList = new List<Contact>();
        contactList.add(request.contact);

        Database.SaveResult[] srList = Database.insert(contactList, true);

        CreateContactResult contactResult = new CreateContactResult();
            for(Database.SaveResult sr: srList) {
                if (sr.isSuccess()) {
                    contactResult.isSuccess = sr.isSuccess();
                    contactResult.contactId = sr.getId();
                }
                else {
                    for(Database.Error err : sr.getErrors()) {
                        contactResult.errorMessage = err.getStatusCode() + ': ' + err.getMessage();
                    }
                }
            }

    return contactResult;
    }
}

下面是 的配置文件。CreateContactAction

<!--CreateContactAction.cls-meta.xml-->

<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="CreateContactAction">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>

这些 HTML、CSS、JavaScript 和配置文件定义操作的自定义属性编辑器组件。createContactActionEditor

组件的 HTML 模板定义了 Flow Builder 中自定义属性编辑器的 UI。

<!--createContactActionEditor.html-->

<template>
  <div class="slds-m-top_small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">
      Contact Primary Information
    </h2>

    <lightning-input
      label="First Name"
      value={defaultContact.FirstName}
      onchange={handleFirstNameChange}
    >
    </lightning-input>

    <lightning-input
      label="Last Name"
      value={defaultContact.LastName}
      onchange={handleLastNameChange}
    >
    </lightning-input>
  </div>

  <div class="slds-m-top_small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">Contact Source</h2>

    <lightning-input
      label="European Country Code"
      value={defaultContact.European_Country_Code__c}
      onchange={handleCountryCodeChange}
    >
    </lightning-input>
  </div>
</template>

此示例显示自定义属性编辑器 UI。

初始化自定义属性编辑器组件时,其 JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中更改值时,自定义属性编辑器组件会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

//createContactActionEditor.js

import { LightningElement, api } from "lwc";

export default class CreateContactActionEditor extends LightningElement {
  @api
  inputVariables;

  defaultContact = {
    attributes: {
      type: "Contact",
    },
    European_Country_Code__c: "FRA",
  };

  get contact() {
    const param = this.inputVariables.find(({ name }) => name === "contact");
    return param && param.value;
  }

  handleFirstNameChange(event) {
    this.defaultContact["FirstName"] = event.detail.value;
    this.handleContact();
  }

  handleLastNameChange(event) {
    this.defaultContact["LastName"] = event.detail.value;
    this.handleContact();
  }

  handleCountryCodeChange(event) {
    this.defaultContact["European_Country_Code__c"] = event.detail.value;
    this.handleContact();
  }

  handleContact() {
    const newValue = JSON.stringify(this.defaultContact);
    const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
      bubbles: true,
      cancelable: false,
      composed: true,
      detail: {
        name: "contact",
        newValue,
        newValueDataType: "SObject",
      },
    });
    this.dispatchEvent(valueChangedEvent);
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用该接口。inputVariables

初始化自定义属性编辑器后,从 Flow Builder 接收可调用操作中输入变量的值。缺省值为 type 和 设置。当您对 sObject 数据类型的输入使用文本值时,请指定该值,例如 。inputVariablesEuropean_Country_Code__ctypeContact

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[{
    name: 'contact',
    value: '{
        "attributes": {
            "type": "Contact"
        },
        "FirstName" : "",
        "LastName": "",
        "European_Country_Code__c" : "FRA"
    }',
    valueDataType: 'SObject'
}]

该方法获取输入变量的值,以便在自定义属性编辑器中使用。get contact()

当管理员在自定义属性编辑器中输入输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleContactconfiguration_editor_input_value_changed

下面是 的配置文件。createContactActionEditor

<!---createContactActionEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <!--isExposed can be true or false-->
    <isExposed>true</isExposed>
</LightningComponentBundle>

自定义属性编辑器 JavaScript 接口

自定义属性编辑器使用这些 JavaScript 函数与 Flow Builder 进行通信。

输入变量

该接口提供有关 FlowScreenField 元数据的数据。inputVariables

_inputVariables = [];

@api
get inputVariables() {
    return this._inputVariables;
}

// Set a field with the data that was stored from the flow.
set inputVariables(variables) {
    this._inputVariables = variables || [];
}

中的数据结构包括每个输入变量的名称、值和数据类型。_inputVariables

[{
    name: 'volume',
    value: '10',
    valueDataType: 'Number'
}]

有关流元数据的更多信息,请参阅流元数据 API。

builder上下文

该接口提供有关流中元素和资源的数据。例如,和数据结构包括输入变量的名称和类型。在 Flow Builder 中,管理员可以将有关其他元素和资源的数据用作屏幕组件输入属性的自定义属性编辑器的输入。builderContextscreensactionCalls

从界面传递到自定义属性编辑器的数据结构包括流中的元素和资源。builderContext

{
    actionCalls: [],
    apexPluginCalls: [],
    constants: [],
    formulas: [],
    recordCreates: [],
    recordDeletes: [],
    recordLookups: [],
    recordUpdates: [],
    screens: [],
    stages: [],
    textTemplates: [],
    variables: []
}

有关流元数据的更多信息,请参阅流元数据 API。

在以下示例中,开发人员创建自定义流屏幕组件及其自定义属性编辑器。在 Flow Builder 中,管理员使用组合框设置电子邮件的发件人姓名。当用户运行流程时,流程屏幕会显示电子邮件的选定名称。

以下 HTML、JavaScript 和配置文件定义自定义流屏幕组件。

<!--htmlEmail.html-->
<template>
  <p>Selected sender's name is: {senderName}</p>
</template>

此 JavaScript 文件定义了一个公共属性。senderName

// htmlEmail.js

import { LightningElement, api } from "lwc";

export default class HTMLEmail extends LightningElement {
  @api senderName;
}

此配置文件注册自定义属性编辑器。

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>49.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__FlowScreen</target>
    </targets>
    <masterLabel>HTMLEmail</masterLabel>
    <targetConfigs>
        <targetConfig targets="lightning__FlowScreen" configurationEditor="c-html-email-editor">
            <property name="senderName" type="String" role="inputOnly" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

以下 HTML、JavaScript 和配置文件定义屏幕组件的自定义属性编辑器。

此 HTML 文件定义 Flow Builder 中自定义属性编辑器的 UI。UI 显示一个组合框基础 Lightning Web 组件。

<!--htmlEmailEditor.html-->
<template>
  <div class="slds-p-around_xx-small">
    <lightning-combobox
      name="senderName"
      label="Sender Display Name"
      value={senderName}
      placeholder="Select Sender"
      options={options}
      onchange={handleChange}
    >
    </lightning-combobox>

    <p class="slds-p-top_xx-small">Selected sender's name is: {senderName}</p>
  </div>
</template>

初始化自定义属性编辑器时,JavaScript 类会从 Flow Builder 接收流元数据的副本。如果管理员在自定义属性编辑器中进行更新,则会调度一个事件以将更改传播回 Flow Builder。

// htmlEmailEditor.js
import { LightningElement, api } from "lwc";
export default class HtmlEmailEditor extends LightningElement {
  @api
  inputVariables;

  @api
  builderContext;

  get senderName() {
    const param = this.inputVariables.find(({ name }) => name === "senderName");
    return param && param.value;
  }

  get options() {
    const variables = this.builderContext.variables;
    return variables.map(({ name, value }) => ({
      label: name,
      value: value.stringValue,
    }));
  }

  handleChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("Configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "senderName",
          newValue,
          newValueDataType: "String",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

该方法返回有关使用接口存储的输入变量的信息。该方法返回使用接口方法存储的合并字段列表。自定义属性编辑器将合并字段显示为屏幕组件输入属性的输入值。senderNamesenderNameinputVariablesoptionsbuilderContext

元素信息

该接口提供有关调用自定义属性编辑器的自定义流屏幕组件或自定义操作的数据。使用此接口可以消除屏幕组件或操作的不同实例的歧义。elementInfo

此示例将流元数据存储在 中,但您可以随意命名该字段。_elementInfo

_elementInfo = {};
@api
get elementInfo() {
    return this._elementInfo;
}

// Set a local variable with the data that was stored from flow.
set elementInfo(info) {
    this._elementInfo = info || {};
}

中的数据结构包括流元数据中流元素的 API 名称和类型。_elementInfo

{
    apiName: 'slider',
    type: 'Screen'
}

type 的有效值为:

  • Screen– 屏幕元素
  • Action– 动作元素

驗證

使用该界面在自定义属性编辑器中执行自定义验证。当流程管理员在 Flow Builder 的屏幕编辑器中单击“完成”时,Flow Builder 会评估每个自定义属性编辑器中的函数。如果函数返回 和 数据结构,则屏幕编辑器会显示错误数。validatevalidatekeyerrorString

注意

Flow Builder 仅显示错误数。编写代码以在自定义属性编辑器中显示错误字符串。

此示例将数据存储在字段中,但您可以使用任何字段名称。为了在自定义属性编辑器中显示错误字符串,我们用于查询、设置和报告错误字符串。validitysliderCmp

@api
validate() {
    const sliderCmp = this.template.querySelector('lightning-slider');
    const validity = [];
    if (this.volume < 0 || this.volume > 100) {
        sliderCmp.setCustomValidity('The slider range is between 0 and     100.');
        validity.push({
            key: 'Slider Range',
            errorString: 'The slider range is between 0 and 100.',
        });
    } else {
        sliderCmp.setCustomValidity('');
    }
    sliderCmp.reportValidity();
    return validity;
}

genericTypeMappings

数据结构包括每个输入的名称和值。是泛型输入的名称;例如。是泛型输入的特定值;例如。genericTypeMappingstypeNamesObject‘T__param1’typeValuesObjectAccount

[{
    typeName: 'T__param1',
    typeValue: 'Account'
}]

事件类型

要向 Flow Builder 报告输入值更改,请从自定义属性编辑器的函数中调度事件。设置为 和 true。handleChangebubblescomposed

事件类型的有效值为:

  • configuration_editor_input_value_changed– 一种事件类型,在输入值更改时调度。
  • configuration_editor_input_value_deleted– 删除输入值时调度的事件类型。
  • configuration_editor_generic_type_mapping_changed– 一种事件类型,在通用输入值更改时调度。sObject

这些属性定义用于报告更改的输入。detail

  • name– 屏幕组件的 JavaScript 类中的输入变量。
  • newValue– 输入的新值。
  • newValueDataType– 输入的新数据类型。
  • typeName– 屏幕组件的 JavaScript 类或可调用方法的 Apex 类中的泛型输入。要在屏幕组件的自定义属性编辑器中引用 ,请引用子标记的属性。该值必须位于大括号内,例如。要将属性定义为泛型集合数据类型,请追加 ,例如 。要在自定义属性编辑器中引用可调用操作的 ,请在输入名称和输出名称前面加上 ,例如 。sObjecttypeNamepropertyTypenameproperty type="{T}"sObject[]property type="{T[]}"typeNameT__U__T__param1
  • typeValue– 通用输入或输出的特定值。sObject

例如,当管理员在自定义属性编辑器中输入值 for 时,它会调度一个事件。Flow Builder 接收事件并更新流中的值。volume

handleChange(event) {
    if (event && event.detail) {
        const newValue = event.detail.value;
        const valueChangedEvent = new CustomEvent(
            'configuration_editor_input_value_changed', {
            bubbles: true,
            cancelable: false,
            composed: true,
            detail: {
                name: 'volume',
                newValue,
                newValueDataType: 'Number'
            }
            }
        );
        this.dispatchEvent(valueChangedEvent);
    }
}

流中支持的数据类型

并非所有自定义 Lightning Web 组件数据类型在流程中都受支持。您只能在流程和自定义 Lightning Web 组件之间映射这些类型及其关联的集合类型。

流数据类型Lightning Web 组件数据类型有效值
Apex(流量标签:Apex-Defined)自定义 Apex 类定义字段的 Apex 类。Apex 类中支持的数据类型包括 Boolean、Integer、Long、Decimal、Double、Date、DateTime 和 String。每种数据类型都支持单个值和列表。@AuraEnabled
布尔布尔真实值:true1等效表达式False 值:false0等效表达式
货币整数数值或等效表达式
日期日期"YYYY-MM-DD"或等效表达式
DateTime(流标签:日期/时间)日期时间"YYYY-MM-DDThh:mm:ssZ"或等效表达式
数值或等效表达式
Multipicklist(流标签:Multi-Select Picklist)字符串字符串值或使用分号分隔格式的等效表达式:“Blue;绿;黄色”
选择列表字符串字符串值或等效表达式
sObject(流标签:记录)特定对象的 API 名称,例如 Account 或 Case键值对或等效表达式的映射。流记录值仅映射到类型为特定对象的属性。例如,客户记录变量只能映射到类型为 Account 的属性。流不支持 Object 数据类型。
字符串(流标签:文本)字符串字符串值或等效表达式