Flow 

Flow Builder 允许管理员使用流自动执行业务流程。了解如何开发和配置 Lightning Web 组件,以用作 Flow Builder 中操作和屏幕组件的流屏幕组件和自定义 UI。

创建流屏组件

正如管理员在 Lightning App Builder 中配置记录页面的用户体验一样,他们使用流屏幕组件为流用户执行相同的操作。每个屏幕都由一个或多个屏幕组件组成。

为流屏幕配置组件

要在流程屏幕中使用自定义 Lightning Web 组件,请将一些元数据添加到组件的配置文件中。

componentName.js-meta.xml 文件定义组件的元数据值,包括用于流屏幕的组件的设计配置。

  • 若要使组件在流屏幕中可用,请添加目标。lightning__FlowScreen
  • 若要向组件添加输入字段,请添加属性。targetConfig
  • 若要将属性限制为 或 ,请使用该特性。例如,如果某个属性限制为 ,则用户无法从 Lightning 记录页面设置其值。如果未指定属性,则默认值允许输入和输出。inputOnlyoutputOnlyroleoutputOnlyrole

请参阅 XML 配置文件元素的完整列表。

此示例组件有 5 个流屏幕输入字段。该属性设置为 。startDateinputOnly

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>47.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel>Best Component Ever</masterLabel>
  <description>This is a demo component.</description>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen">
      <property name="startDate" label="Start Date" type="Date" role="inputOnly" />
      <property name="account" label="Account Chosen" type="@salesforce/schema/Account" />
      <property name="annualRevenue" label="Annual Revenue" type="Integer" role="outputOnly" />
      <property name="name" label="Account Name" type="String" />
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

验证自定义流屏幕组件的用户输入

向自定义屏幕组件添加验证。

要使用 Flow 的验证功能,请在组件的 JavaScript 文件中创建一个调用的函数。validate()

// sampleValidate.js
@api
validate() {
  if(/* true conditions */) {
    return { isValid: true };
    }
  else {
    // If the component is invalid, return the isValid parameter
    // as false and return an error message.
    return {
      isValid: false,
      errorMessage: '/*A message that explains what went wrong.*/'
    };
  }
}

注意

箭头函数表达式不适用于 的组件中的验证。targetlightning__FlowScreen

在自定义 Lightning Web 组件中嵌入流程

嵌入来自任何 Lightning Web 组件的屏幕流,以自定义完成行为、设置自定义样式或从 Lightning Web 组件启动流程。

在自定义 Lightning Web 组件中创建和启动流程

创建并启动从任何 Lightning Web 组件到您的屏幕流。

lightning-flow表示 Lightning 运行时中的流程面试。若要在组件中创建流,请将组件的属性设置为要使用的流的 API 名称。要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。lightning-flowflow-api-name

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

此示例创建并启动“调查客户”流。

<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name="Survey_customers"> </lightning-flow>
</template>

您可以通过将属性设置为输入值数组来提供面试的初始输入。flow-input-variables

此示例通过传入流程的初始值来创建和启动面试。它使用事件处理程序处理面试中的更改。onstatuschange

<!-- myComponent.html -->
<template>
  <lightning-flow
    flow-api-name={flowName}
    flow-input-variables={inputVariables}
    onstatuschange={handleStatusChange}>
  </lightning-flow>
</template>
// myComponent.js
import { LightningElement } from "lwc";

export default class MyComponent extends LightningElement {
  opportunityId;
  accountId;
  customerLocation;

  get flowName() {
    if (this.customerLocation === "USA") {
      flowname = "Survey_USA";
    } else {
      flowname = "Survey_General";
    }
  }

  get inputVariables() {
    return [
      {
        // Match with the input variable name declared in the flow.
        name: "OpportunityID",
        type: "String",
        // Initial value to send to the flow input.
        value: this.opportunityId,
      },
      {
        // Match with the input variable name declared in the flow.
        name: "AccountID",
        type: "String",
        // Initial value to send to the flow input.
        value: this.accountId,
      },
    ];
  }

  handleStatusChange(event) {
    if (event.detail.status === "FINISHED") {
      // set behavior after a finished flow interview.
    }
  }
}

使用注意事项

该组件仅支持该属性的活动流。lightning-flowflow-api-name

该事件返回这些参数。onstatuschange

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

参数类型描述
活动阶段对象[]流中 $Flow.ActiveStages 变量的当前值。在 API 版本 42.0 及更高版本中可用。
当前阶段对象流中 $Flow.CurrentStage 变量的当前值。在 API 版本 42.0 及更高版本中可用。
flowTitle (流标题)字符串流的标签。
帮助文本字符串当前屏幕的帮助文本。在 API 版本 42.0 及更高版本中可用。
GUID字符串面试的 GUID。在 API 版本 42.0 及更高版本中可用。
输出变量对象[]流输出变量的当前值。
地位字符串面试的状态。流程面试的有效状态为:STARTED:面试成功开始。PAUSED:采访成功暂停。FINISHED:屏幕完成的流程面试。FINISHED_SCREEN:没有屏幕的流的面试已完成,组件显示默认屏幕,其中包含以下消息:您的流已完成。ERROR:出了点问题,面试失败了。

自定义流的完成行为

每个流组件都包括导航按钮“后退”、“下一步”、“暂停”和“完成”,这些按钮在流中导航。默认情况下,当流程完成时,组件会重新加载新面试的第一个屏幕。若要自定义流程完成时发生的情况,请在状态为 FINISHED 时为操作添加事件处理程序。onstatuschange

设置流输入变量

在自定义组件中嵌入流时,通过初始化流的变量为流提供更多上下文。若要在组件中创建流,请将组件的属性设置为要使用的流的 API 名称。lightning-flowlightning-flowflow-api-name

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

为流创建输入变量

在组件的 Javascript 文件中,创建一个映射列表,并将该列表传递给属性。flow-input-variables

注意

您只能在面试开始时设置变量,并且您设置的变量必须允许输入访问。如果引用的变量不允许输入访问,则会忽略设置该变量的尝试。

对于您设置的每个变量,请提供变量的名称、类型和值。对于 type (类型),请使用 API 名称作为流数据类型。例如,对于记录变量,请使用 SObject,对于文本变量,请使用 String。

{
  name : "varName",
  type : "flowDataType",
  value : valueToSet
},
{
  name : "varName",
  type : "flowDataType",
  value : [ value1, value2 ]
}, ...

JavaScript 文件中的此方法返回一个数字变量、一个日期集合变量和几个记录变量的值数组。Flow Builder 中的 Record 数据类型与此处的 SObject 相对应。

// myComponent.js
get inputVariables() {
  return [
    { name: 'numVar', type: 'Number', value: 30 },
    { name: 'dateColl', type: 'String', value: [ '2016-10-27', '2017-08-01' ] },
    // Sets values for fields in the account record (sObject) variable.
    // Id uses the value of the accountId property. Rating uses a string.
    { name: 'account', type: 'SObject', value: {
      'Id': this.accountId,
      'Rating': 'Warm'
    }},
    // Set the contact record (sObject) variable to the value of the contact property.
    // We're assuming the property contains the entire sObject for a contact record.
    { name: 'contact', type: 'SObject', value: this.contact }
  ]
}

示例:将帐户数据传递到流

此示例组件通过 Apex 控制器获取帐户。Apex 控制器通过 JavaScript 文件中的线路将数据传递到流的记录变量。

<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name="myFlow" flow-input-variables={inputVariables}> </lightning-flow>
</template>
// AccountController.apex
public with sharing class AccountController {
    @AuraEnabled(cacheable=true)
    public static Account getAccount() {
        return [SELECT Id, Name, LastModifiedDate, FROM Account LIMIT 1];
    }
}
// myComponent.js
import { LightningElement, track, wire } from "lwc";
import getAccount from "@salesforce/apex/AccountController.getAccount";

export default class MyComponent extends LightningElement {
  @track
  inputVariables = [];

  @wire(getAccount)
  getAccountFromApex({ error, data }) {
    if (error) {
      console.log("Failed to get account data.");
    } else if (data) {
      this.inputVariables = [
        {
          name: "account",
          type: "SOjbect",
          value: data,
        },
      ];
    }
  }
}

从流输出变量中获取值

在组件中嵌入流时,可以显示或引用流的变量值。lightning-flow

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

使用 onstatuschange 事件处理程序

若要从流的输出变量中获取值,请使用事件处理程序。输出变量以数组形式返回。该变量必须允许输出访问。如果引用的变量不允许输出访问,则会忽略获取该变量的尝试。onstatuschange

示例:显示流的输出变量

此示例获取 和 的流输出变量,并将其显示在模板中。accountNamenumberOfEmployees

<!-- myComponent.html -->
<template>
  <p>{accountName}</p>
  <p>{numberOfEmployees}</p>
  <lightning-flow flow-api-name="myFlow" onstatuschange={handleStatusChange}> </lightning-flow>
</template>
// myComponent.js
import { LightningElement, track, wire } from "lwc";

export default class MyComponent extends LightningElement {
  accountName;
  numberOfEmployees;

  handleStatusChange(event) {
    if (event.detail.status === "FINISHED") {
      const outputVariables = event.detail.outputVariables;
      for (let i = 0; i < outputVariables.length; i++) {
        const outputVar = outputVariables[i];
        if (outputVar.name == "accountName") {
          this.accountName = outputVar.value;
        } else {
          this.numberOfEmployees = outputVar.value;
        }
      }
    }
  }
}

控制流程面试完成后发生的情况

通过将流嵌入到自定义组件中,可以确定流完成时发生的情况。lightning-flow

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

使用 lightning-flow 嵌入流

默认情况下,当流程用户单击“完成”时,将开始新的面试,并且用户将再次看到流程的第一个屏幕。通过将流嵌入到自定义组件中,可以使用事件处理程序来调整流完成时发生的情况。lightning-flowonstatuschange

  • 若要重定向到其他页面,请使用导航服务。
  • 要控制自动启动的流程完成时发生的情况,请检查FINISHED_SCREEN状态。
<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name="myFlow" onstatuschange={handleStatusChange}> </lightning-flow>
</template>
// myComponent.js
handleStatusChange(event) {
    if(event.detail.status === 'FINISHED') {
        // Redirect to another page in Salesforce., or
        // Redirect to a page outside of Salesforce., or
        // Show a toast, or something else
    }
}

示例:在流程完成后导航到记录

此示例使用该方法将用户重定向到在流中创建的案例。 lightning/navigationNavigationMixin.Navigate

// myComponent.js
import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class MyComponent extends NavigationMixin(LightningElement) {
  navigateToRecord(recordId) {
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId,
        actionName: "view",
      },
    });
  }

  handleStatusChange(event) {
    if (event.detail.status === "FINISHED") {
      const outputVariables = event.detail.outputVariables;
      for (let i = 0; i < outputVariables.length; i++) {
        const outputVar = outputVariables[i];
        if (outputVar.name === "redirect") {
          this.navigateToRecord(outputVar.value);
        }
      }
    }
  }
}

恢复流程面试

您可以通过将组件嵌入到自定义 LWC 组件中来自定义用户恢复访谈的方式和位置。lightning-flow

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

处理暂停的面试

默认情况下,用户可以从其主页上的“暂停的访谈”组件中恢复他们暂停的访谈。若要自定义用户恢复访谈的方式和位置,请将组件嵌入到自定义 LWC 组件中,并将访谈 ID 传递到属性中。lightning-flowflow-interview-id

此示例说明如何恢复面试或开始新的面试。当用户单击联系人记录中的“调查客户”时,该组件将执行其中一项操作。lightning-flow

  • 如果用户对“调查客户”流有任何暂停的访谈,则该组件将恢复第一个访谈。lightning-flow
  • 如果用户对调查客户流没有任何暂停的访谈,则该组件将启动一个新访谈。lightning-flow
<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name={flowName} flow-interview-id={pausedInterviewId}>
  </lightning-flow>
</template>

示例:使用 Apex 恢复或开始新的面试

此 Apex 控制器通过执行 SOQL 查询来获取暂停访谈的列表。如果没有暂停的访谈,则查询将返回 null 值,然后组件将启动新的访谈。如果查询返回至少一个采访,则该组件将恢复该列表中的第一个采访。

// InterviewsController.apex
public class InterviewsController {
    @AuraEnabled(cacheable=true)
    public static String getPausedId() {
        // Get the ID of the running user.
        String currentUser = UserInfo.getUserId();
        // Find all of that user’s paused interviews for the Survey customers flow.
        List<FlowInterview> interviews =
             [ SELECT Id FROM FlowInterview WHERE CreatedById = :currentUser AND
                 InterviewLabel LIKE '%Survey customers%'];
        if (interviews == null || interviews.isEmpty()) {
            return null; // early out
        }
        // Return the ID for the first interview in the list.
        return interviews.get(0).Id;
    }
}

如果 Apex 控制器返回采访 ID,则传递到该属性。如果 Apex 控制器返回空访谈 ID,则组件通过将流名称传递给属性来启动新的访谈。pausedInterviewIdflow-interview-idflow-api-name

// myComponent.js
import { LightningElement, wire } from "lwc";
import getPausedId from "@salesforce/apex/InterviewsController.getPausedId";

export default class MyComponent extends LightningElement {
  flowName;
  pausedInterviewId;

  @wire(getPausedId)
  getPausedInterviewId({ error, data }) {
    if (error) {
      // start a new interview since no interview id was returned.
      this.flowName = "Survey_customers";
    } else if (data) {
      // resume the flow with the returned interview id.
      this.pausedInterviewId = data;
    }
  }
}

流屏组件的运行时注意事项

为流程配置组件时,请查看这些注意事项,以定义属性和流程运行时行为。

  • 处理 null 默认输入值。如果流程管理员未为自定义屏幕组件设置默认输入值,则流程生成器会在组件运行时传递一个值。若要在运行时设置默认值,请添加处理程序。nullnull
  • 通知运行时属性更改。Lightning Web 组件使用事件来报告从组件到流程的更改。为了通知流运行时属性更改,组件会触发事件。例如,在满足条件时使用条件可见性呈现屏幕组件时,或者将输出属性的值映射到流变量时,请使用此事件。有关代码示例,请参见。FlowAttributeChangeEventlightning-flow-support

设置屏幕流组件的反应性

屏幕流反应性意味着使屏幕流组件更改影响另一个同一屏幕组件。

在 Flow 构建器中添加和配置自定义 Lightning Web 组件之前,请创建自定义 LWC。

如果您计划构建反应式屏幕组件或使用支持的组件,则需要了解每个组件的注意事项。反应性包括:

  • 确定哪个屏幕组件是源,哪个组件是反应式组件。
  • 了解每组组件的不同交互。

示例:标准流量组件到标准流量组件

使用标准 Flow 组件是实现反应性的最简单方法。

使用标准 Flow 组件,您可以添加组件,为每个组件提供 API 名称和标签(如果需要),标识源和反应式组件,然后保存并运行流。

要使 Name 组件的 First Name 字段响应并显示来自 Text 组件的所有文本输入,请执行以下操作:

  1. 在流程中,添加组件和组件,并为每个组件提供标签。TextName
  2. 在组件的 First Name’s source 字段中,选择组件作为源。源可以是同一类型的任何组件,在本例中,Text 组件的类型和 Name 组件的 First Name 字段的类型为 String。NameText
  3. 保存并运行 Flow,然后在组件的输入中键入 .键入每个字符后,“名字”字段会立即更新。TextThis is Reactivity

示例:标准流组件到自定义 Lightning Web 组件

让您的自定义组件对标准 Flow 组件中的更改做出反应。

要创建自定义组件并将其添加到 Flow Builder 中,请执行以下操作:colorName

  1. 添加“文本”组件和“自定义”组件,并为每个组件提供标签。colorName
  2. 在 colorName 的属性中,选择组件作为“颜色名称”字段的源。Text

对文本输入所做的任何更改都会自动反映在自定义 Lightning Web 组件 .例如,在文本输入中输入洋红色会导致 LWC 显示具有相同颜色 magenta 样式的颜色名称。colorName

<!-- colorName.html -->
<template>
  <p>
    Color name has the same color :
    <span style={colorStyle}>{color}</span>
  </p>
</template>
// colorName.js
import { LightningElement, api } from "lwc";

export default class colorName extends LightningElement {
  @api color;

  get colorStyle() {
    return "color:" + this.color;
  }
}
// colorName.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
 <apiVersion>52.0</apiVersion>
 <isExposed>true</isExposed>
 <masterLabel>Color Name</masterLabel>
 <description>Reactive Color Name</description>
 <targets>
     <target>lightning__FlowScreen</target>
 </targets>
<targetConfigs>
      <targetConfig targets="lightning__FlowScreen">
          <property name="color" label="Name of Color" type="String" />
      </targetConfig>
</targetConfigs>
</LightningComponentBundle>

示例:将 Lightning Web 组件自定义为标准流组件

使自定义文本组件对标准 Flow 组件做出反应。

  1. 使用示例中引用的装饰器创建公共字段。@apicustomText.js
  2. 在文件中添加具有示例中引用的适当类型的目标配置。.js-meta.xmlcustomText.js-meta.xml
  3. 添加附加了事件处理程序的输入字段以存储用户输入。
  4. 在事件处理程序中,触发组件中定义的事件。事件名称必须与公共字段的名称匹配,才能使反应性起作用。由于 Flow Runtime 的性质,setter 方法在触发事件后调用,并在反应性导致对公共字段的更改时调用该方法。FlowAttributeChangeflow-supportFlowAttributeChangeFlowAttributeChange
  5. 创建自定义组件后,将该组件添加到带有标签的 Flow 构建器中。
  6. 若要使 Text 组件对自定义组件做出反应,请将 Text 组件上的默认值源配置为自定义组件的公共属性。
<!-- customText.html -->
<template>
  <lightning-input type="text" label="This is custom text" onchange={handleInputChange}>
  </lightning-input>
</template>
// customText.js
import LightningElement, api, track } from 'lwc';
import { FlowAttributeChangeEvent } from 'lightning/flowSupport';

export default class customText extends LightningElement {
   @track _input;

   @api
   set customTextValue(input) {
       if (input) {
           this._input = input;
       }
   };
   get customTextValue() {
       return this._input;
   }

   handleInputChange(event) {
       const attributeChangeEvent = new FlowAttributeChangeEvent('customTextValue', event.target.value);
       this.dispatchEvent(attributeChangeEvent);
   }
}
// customText.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
 <apiVersion>52.0</apiVersion>
 <isExposed>true</isExposed>
 <masterLabel>Custom Text</masterLabel>
 <description>Custom Text Example</description>
 <targets>
     <target>lightning__FlowScreen</target>
 </targets>
<targetConfigs>
      <targetConfig targets="lightning__FlowScreen">
          <property name="customTextValue" label="Custom Text Value" type="String" />
      </targetConfig>
</targetConfigs>
</LightningComponentBundle>

示例:自定义 Lightning Web 组件到自定义 Lightning Web 组件

使自定义 Lightning Web 组件对另一个自定义组件做出反应。

此示例假定组件和组件都已添加到 Flow Builder 中。该组件用于控制组件。customTextcolorNamecustomTextcolorName

  1. 添加组件和组件,并为每个组件提供标签。customTextcolorName
  2. 在组件的 Name of Color 字段中,选择组件作为源。colorNamecustomText

对组件所做的任何更改都会自动反映在 中的颜色公共字段中。例如,输入输入会导致显示具有相同颜色样式的颜色名称,即洋红色。customTextcolorNamemagentacustomTextcolorName

屏幕流中反应性的最佳做法

确保您的 Lightning Web 组件在 Flow 运行时引擎中很好地集成,并按预期工作以实现 Screen Flow 反应性。

状态管理和反应性

这些部分介绍了在屏幕流中具有反应性的状态管理,包括:

  • LWC 状态管理与 Aura 有何不同
  • 状态管理在新的 LWC Flow Runtime 中的工作原理
  • 为屏幕流构建 LWC 时要遵循的状态管理和事件最佳实践

Aura 与 LWC 中的状态管理

Aura 组件和 LWC 的状态管理遵循不同的范式。在 Aura 组件中,由它们所属的组件(包括外部组件)查看和修改。LWC 被设计为在内部和外部状态之间具有明确的分离。声明的变量只能由 LWC 的父级修改。没有注释的变量和带有注释的变量被视为内部状态,可以在定义它们的 LWC 中更改。<aura:attributes />@api@api@track

屏幕流中的 LWC 状态管理

Flow 运行时遵循 LWC 状态管理设计原则。当它渲染的 LWC 组件不修改其自身属性时,它效果最佳。相反,组件通过触发请求更改,这是必不可少的,原因有几个。@apiFlowAttributeChangeEvent

  • 允许其父级控制其属性的组件更容易重用,因为它们允许应用程序控制状态,而不是组件自己的内部业务逻辑。@api
  • 通过触发属性更改事件,Flow 运行时可以准确了解组件状态。Flow 运行时可以控制组件间的交互,例如条件字段可见性,这是反应性的一部分。

使用 LWC linter 规则是确保组件不会修改属性的绝佳方法。在开发环境中设置使用 LWC 的 linter 规则的 linter,特别是确保强制执行该设置。@api

流导航时的状态管理

为了在 Flow Runtime 版本之间保持一致的行为,当用户单击“下一步”或“完成”按钮时,Flow Runtime 会通过提取每个自定义 LWC 组件的当前属性状态来收集值,然后再移动到下一个屏幕或完成流程。此机制可确保不符合规定设计模式的组件在最新的 Flow Runtime 版本中继续工作。强烈建议避免依赖此行为。@api

下面是一个简单的文本输入组件示例,该组件演示了触发而不是更新 LWC 的属性:FlowAttributeChangeEvent@api

@api textValue;

handleTextInputChange(event) {
  const event = new FlowAttributeChangeEvent('textValue', event.target.value);
  this.dispatchEvent(event);
}

不建议使用以下示例。

//Don’t do this
@api textValue;

handleTextInputChange(event) {
  this.textValue = event.target.value;
}

创建 FlowAttributeChangeEvent 实例

该事件使 LWC 能够通知运行时其当前状态。它是 Flow Runtime 状态管理机制的一部分。每当用户交互导致需要更新属性的修改时,都会触发这些事件。FlowAttributeChangeEvent@api

从模块导入。FlowAttributeChangeEventlightning/flowSupport

import { FlowAttributeChangeEvent } from "lightning/flowSupport";

接下来,您可以创建事件的实例。

const attributeChangeEvent = new FlowAttributeChangeEvent(apiParameterName, updatedValue);

FlowAttributeChangeEvent包括两个参数。

  • apiParameterName– 要修改的 API 属性的名称。
  • updatedValue– Flow 属性的更新值。

将字符串传递给与 JavaScript 和文件中显示的 API 属性匹配的字符串。apiParameterName.js-meta.xml

例如,请注意 how 在所有 3 个地方都是一致的:exampleApiParameterName

  • 在 LWC 的文件中声明属性:.js-meta.xml<property name="exampleApiParameterName" label="Example Api Parameter" .../>
  • 在 LWC 的文件中声明 API 属性:.js@api exampleApiParameterName;
  • 构造实例:FlowAttributeChangeEventconst changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", "newValue");

传递 以匹配文件中声明的数据类型。updatedValue.js-meta.xml

  • 将属性声明为 Record:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", { StringFieldName: "stringValue", BooleanFieldName: false, NumberFieldName: 42, DateTimeFieldName: "2022-12-15T23:35:24.000Z", });
  • 将属性声明为字符串:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", "newValue");
  • 将属性声明为数字:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", 6);
  • 将属性声明为布尔值:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", true);

触发 FlowAttributeChangeEvent 事件

构造实例后,可以使用该方法触发事件。FlowAttributeChangeEventthis.dispatchEvent(eventToFire)

const attributeChangeEvent = new FlowAttributeChangeEvent("apiPropertyName", 10);
this.dispatchEvent(attributeChangeEvent);

FlowAttributeChangeEvent 最佳实践

请遵循这些示例并避免有问题的用法,以减少流程版本升级后的意外行为。这些最佳实践使您能够更轻松地维护组件。FlowAttributeChangeEvent

  • 在事件处理程序或在事件处理程序中调用的方法中触发事件。
  • 将事件的 value 参数限制为以下数据类型:String、number、boolean、JSON(用于记录类型)。
  • 确保事件的 value 参数的 Flow 数据类型与 LWC 属性的数据类型匹配。@api
  • 在适当的情况下,通过使用 get/set 模式来响应对属性的更改。@api

此示例演示如何使用 getter 和 setter 对属性的更新进行计数,而不是在触发属性更改事件之前递增计数器。这两种模式都是有效的,但它们获得的结果略有不同。@api

@api textValue;
textValueToRender;
changeCounter = 0;

get textValue() {
  return this.textValueToRender;
}

// Due to the nature of the Flow Runtime, this setter method
// is called after the FlowAttributeChangeEvent fired below. It also
// is invoked when reactivity leads to a change to the textValue property.
set textValue(newTextValue) {
  this.changeCounter++;
  this.textValueToRender = newTextValue;
}

handleTextInputChange(event) {
  const event = new FlowAttributeChangeEvent('textValue', event.target.value);
  this.dispatchEvent(event);
}

在这种情况下,每当用户在文本输入中输入更改以及 Flow Runtime 确定属性已更改时,都会递增。这种方法考虑了组件初始化和通过反应性进行的跨组件交互。使用中间变量呈现来自 set 方法的更新。在此示例中,填充此角色。this.changeCountertextValuetextValueToRender

下面的代码示例在触发属性更改事件之前递增计数器。此方案不使用 get/set 模式。

@api textValue;
changeCounter = 0;

handleTextInputChange(event) {
  this.changeCounter++;
  const event = new FlowAttributeChangeEvent('textValue', event.target.value);
  this.dispatchEvent(event);
}

在这种情况下,每当用户在文本输入中输入更改时,都会递增。当反应性更改此字段的值时,计数器不会更新。this.changeCounter

使用无注释或属性来维护可修改的本地组件状态。@track

下面的示例演示一个颜色选取器,该选取器向用户显示输入文本框和一些色板。颜色选取器组件返回到流中,因此只需要注释。and 成员仅是内部成员,不需要任何装饰器。colorcolor@apiselectedSwatchIdinputValue

//colorPicker.js

@api color;

inputValue;
selectedSwatchId;


ALL_SWATCHES =[{
  'id': 1,
  'color': 'red'
}, {
  'id': 2,
  'color': 'blue'
}, {
  'id': 3,
  'color': 'green'
}, {
  'id': 4,
  'color': 'yellow'
}];

set color(newColor) {
  // Set the content of the input text to the color value:
  this.inputValue = newColor;

  // If the color matches a swatch, highlight it in the UI:
  const foundSwatch = this.ALL_SWATCHES.find(swatch => swatch.color === newColor);
  this.selectedSwatchId = foundSwatch && foundSwatch.id;
}

get color() {
  return this.inputValue;
}

handleSwatchSelected(event) {
  // Select get the swatch data for the clicked swatch:
  const selectedSwatch = this.ALL_SWATCHES.find(swatch => swatch.id === event.target.dataset.id);
  const changeEvent = new FlowAttributeChangeEvent('color', selectedSwatch.color);
  this.dispatchEvent(changeEvent);
}

handleInputValueChange(event) {
  this.inputValue = event.target.value;
  const changeEvent = new FlowAttributeChangeEvent('color', this.inputValue);
  this.dispatchEvent(changeEvent);
}

使用 get 方法将多个属性组合在一起,为视图构造派生变量。@api

//Salutation.js
@api firstName;
@api lastName;
@api ageName;

get salutation() {
  return `Hello ${this.firstName} ${this.lastName}, you are ${this.age} years old.`;
}
<!-- Salutation.html -->
<template>
  <div>{salutation}</div>
</template>

在参与内部组件状态管理所需的派生成员变量的每个属性的 set 方法中应用相同的逻辑,就像在比上一个示例更复杂的方案中一样。此逻辑可确保对任何贡献属性所做的更改都会导致值正确呈现,而不管设置属性的顺序如何。@api

//Dropdown.js
set optionLabels(newOptionLabels) {
  this.internalOptionLabels = newOptionLabels;
  this.options = this.computeOptions();
}

set optionValues(newOptionValues) {
  this.internalOptionValues = newOptionValues;
  this.options = this.computeOptions();
}

set value(newValue) {
  this.internalValue = newValue;
  this.options = this.computeOptions();
}

handleSelect(event) {
  const selectedValue = event.srcElement.value;
  const isAlreadySelected = this.options.some(option => {
    return option.isSelected && option.value === selectedValue;
  });

  if (!isAlreadySelected) {
    const attributeChange = new FlowAttributeChangeEvent('value', selectedValue);
    this.dispatchEvent(attributeChange);
  }
}

computeOptions() {
  if (this.internalOptionLabels.length !== this.internalOptionValues.length) {
    return [];
  }

  return this.internalOptionLabels.map((label, index) ==> {
    const value = this.internalOptionValues[index];
    const isSelected = this.internalValue === value;
    return {
      label,
      value,
      isSelected
    };
  });
}

不要修改属性。而是开火。@apiFlowAttributeChangeEvents

不要在构造后修改参数。默认情况下,实例是组合和冒泡的。FlowAttributeChangeEventFlowAttributeChangeEvent

const changeEvent = new FlowAttributeChangeEvent("prop", "value");
changeEvent.bubbles = false; // Don’t do this
changeEvent.composed = false; // Don’t do this

避免同时发生射击和事件,因为它可能导致争用条件。我们永远无法保证您的 Lightning Web 组件在导航过程开始时有时间呈现更新的值。FlowAttributeChangeEventsFlowNavigationXxx

派生属性最佳实践

在流组件中,派生属性是其值由同一组件的其他属性确定的属性。该值可能与一个或多个其他属性相关联。例如,数据表组件的参数是派生属性,因为它的值由属性的值确定。具体而言,参数的值是属性的第一个元素的值。firstSelectedRowselectedRowsfirstSelectedRowselectedRows

创建包含派生属性的流屏幕组件时,请遵循此处概述的最佳实践,以确保组件在响应式框架中正常运行。通过这些最佳做法,您可以避免与以下方面相关的问题:

反应性链

当对一个组件的属性进行更改导致对其他组件的属性进行级联更改时,就会发生反应链。例如,用户选择数据表组件中的一行,这将更改组件的属性值,从而更改 Name 组件的属性。对 Name 组件的更改会更改 Text 组件的属性。firstSelectedRowfirstNamevalue

在重新访问的屏幕上保留值

当管理员配置屏幕时,您可以选择在用户离开时流是否保留用户指定的值,然后使用“上一个”或“下一个”按钮返回到屏幕。

若要确保派生属性在具有反应性组件的流屏幕中按预期方式运行,请遵循以下准则:

  1. 务必在驱动更改的属性的方法中为派生属性触发事件。此外,在组件的方法中触发派生属性的事件,例如:FlowAttributeChangeEventsetFlowAttributeChangeEventconnectedCallback// 'Driving' attribute set method set stringToCount(newStringToCount) { this._stringToCount = newStringToCount; // Fire an event for 'derived' attribute const lengthChangeEvent = new FlowAttributeChangeEvent('stringLength', this._stringToCount.length); this.dispatchEvent(lengthChangeEvent); } connectedCallback() { // Fire an event for 'derived' attribute here as well const lengthChangeEvent = new FlowAttributeChangeEvent('stringLength', this.\_stringToCount.length); this.dispatchEvent(lengthChangeEvent); }
  2. 不要在方法中省略事件。 您必须将事件包含在两个位置。当流执行驱动更改的属性的 in 方法时,组件不在 DOM 中,事件基本上无处可去。在方法中添加事件可确保当流将组件添加到 DOM 时,流运行时可以使用该事件。FlowAttributeChangeEventconnectedCallbackFlowAttributeChangeEventFlowAttributeChangeEventsetconnectedCallback
  3. 不要在方法中省略事件。 触发驱动更改的属性的 in 方法可确保将更改应用于驱动更改的属性和派生属性。因此,包含自定义组件的反应性链可以正常工作。FlowAttributeChangeEventsetFlowAttributeChangeEventset
  4. 不要通过使用来延迟触发方法内部来省略该方法。 延迟可确保当流首次调用该方法时,组件位于 DOM 中。但是,延迟还意味着组件在流初始化屏幕后触发事件。因此,流运行时始终覆盖保留的值,并否决重新访问的值的设置。connectedCallbackPromise.resolve().then(...)FlowAttributeChangeEventsetFlowAttributeChangeEventsetset stringToCount(newStringToCount) { this._stringToCount = newStringToCount; const lengthChangeEvent = new FlowAttributeChangeEvent('stringLength', this._stringToCount.length); // This code overwrites preserved values. Don't do this. Promise.resolve().then(() => { this.dispatchEvent(lengthChangeEvent); }); }

导航更改事件最佳实践

除了 之外,您的 Lightning Web 组件还可以触发导航事件以在屏幕之间移动、暂停或完成流程。要使用导航事件,请从以下位置导入这些函数:FlowAttributeChangeEventlightning/flowSupport

  • FlowNavigationNextEvent
  • FlowNavigationBackEvent
  • FlowNavigationPauseEvent
  • FlowNavigationFinishEvent

触发 FlowNavigationEvent

此代码片段介绍如何导入和触发导航事件。当该示例使用 时,相同的结构适用于每个可用的导航目标。FlowNavigationNextEvent

import { FlowNavigationNextEvent } from "lightning/flowSupport";

export default class FlowExample extends LightningElement {
  handleCustomNavigationButtonClick() {
    const nextEvent = new FlowNavigationNextEvent();
    this.dispatchEvent(nextEvent);
  }
}

导航事件允许您的 Lightning Web 组件包含其他控制机制。对最终用户交互做出反应时触发导航事件。使用导航事件时,请参阅以下准则:

  • 在事件处理程序(或事件处理程序调用的方法中)触发导航事件。
  • 不要在事件处理程序之外触发导航事件,因为这会导致糟糕的用户体验。
  • 不要在生命周期处理程序(如 和)中触发导航事件。renderedCallbackconnectedCallback
  • 将跳过屏幕的逻辑放在 Flow Decision Nodes 中,而不是放在屏幕的生命周期中。
  • 不要在虚拟屏幕中执行导航,因为这可能会导致 Flow 性能不佳。
  • 如果您遇到以下情况:由于数据尚不可用于 Flow Decision Nodes,因此必须在屏幕的初始化阶段完成导航,请在 Idea Exchange 中发布升级请求