DEX475

Flows

课程介绍

同学们好,今天这一页Slide,我们来聊聊Lightning Web Components怎么跟Flow Builder这个自动化工具集成。Flow Builder呢,就是让管理员不用写代码,拖拖拽拽就能做出业务流程的工具。而当我们写LWC时,经常需要把这些自定义的组件放进流程里去,或者把整个流程嵌入到我们的组件里。集成方式主要有两种,Slide上写得很清楚。 第一种,把你的LWC变成一个,流屏幕组件,。意思就是,流程运行到某个步骤时,屏幕上显示的就是你这个LWC。要这么做,组件的配置文件里必须声明`lightning__FlowScreen`这个目标,并且你要用`@api`装饰器来定义属性,然后给属性配上角色:`inputOnly`表示这个属性只能从流程接收数据,就像流程传参数给你;`outputOnly`表示你处理完数据后,把结果返回给流程。你可以在配置里直接指定哪些是输入、哪些是输出。 第二种呢,是把整个流当成一个子组件,用`lightning-flow`基础组件嵌入到你的LWC里。这样一来,你就可以在自己的页面里放一个流程,让它跑起来。你可以动态指定要跑哪个流程,还能通过`flow-api-name`和`input-variables`这些属性,把当前页面的数据传进去。 当流程跑起来之后,我们经常需要知道它的状态变化。`lightning-flow`组件有个`onstatuschange`事件,能告诉我们流程现在是开始了(STARTED)、暂停了(PAUSED)、完成了(FINISHED),还是出错了(ERROR)。这个对我们控制页面上的其他元素很有用。 Slide里还提到通过Apex来“设置SObject”和收集输入变量。用大白话讲,就是有时候我们需要用服务器端的方法,帮流程准备好需要的变量,比如查出一组客户数据,然后把它们传给流程。我们就可以在LWC里调用Apex方法,拿到数据后,再把这些数据塞给流程的输入变量,或者从流程的输出变量里读出来存到数据库。 关于导航控制呢,是说当流程结束后,我们可以在组件里监听结束状态,然后决定跳转到哪个页面,比如回到列表页或者别的详情页。另外,如果流程暂停了,比如用户在屏幕组件里填了一半离开,后面还可以恢复这个“采访”(Interview就是一次运行实例),让用户继续填下去。 还有一种很牛的用法,就是构建,反应式屏幕组件,。当你的LWC作为流屏幕时,如果组件内部的属性发生了变化,你可以用`FlowAttributeChangeEvent`主动通知流程:“嘿,我这里的值变了,你可能需要更新别的字段。”这样一来,流程可以实时响应,让整个表单更灵活。Slide里叫它FlowCusteChangeEvents,其实指的是这个事件。 最后,记住几条最佳实践。很重要的一条:,永远不要直接修改用@api声明的属性,。因为这些属性是属于流程管理的,你直接改了会破坏流程的数据一致性。正确做法是,先把值存到内部变量,再通过事件通知流程。另外,善用派生属性来展示数据,别乱改来源。导航事件也要小心触发,别在流程还没彻底结束时就跳走。 好啦,这一章的核心就是这些,把LWC和Flow结合好,你就能做出既灵活又强大、还能让管理员动手配置的低代码业务界面。课后大家可以试着搭一个简单的流程,用LWC接收数据再返回结果,亲身体会一下。

课程章节

本课程共有 8 个章节

  • 1

    Configure a Component for Flow Screens

    第 343 页

    我们来讲讲怎么为流屏幕配置组件。这个东西听起来有点复杂,但其实拆开看就明白了。 首先,要让你的组件出现在 Flow Builder 的屏幕里,你得在组件的配置文件中加上 `lightning__FlowScreen` 这个目标。同时,你还需要在 `targetConfig` 里定义好属性。这些属性就是将来管理员在 Flow 里能设置或接收的值。 接下来,每个属性都有一个“角色”,它控制数据是往哪个方向走的。 - 如果设成 `inputOnly`,那这个值只能在 Flow Builder 里由管理员设置,组件就只能接收,没法改完传回去。 - 如果设成 `outputOnly`,那就反过来,组件会产生一个值,然后往回传给 Flow。 - 要是你不写角色,那就是双向都可以,数据既能进来,也能出去。 属性的类型有好几种,包括最常见的字符串、布尔值、日期、日期时间等标准类型,也可以直接引用一个记录变量,这时候就要用到 `@salesforce/schema` 来指定对象。 别忘了,在 JavaScript 文件里,你必须给这些属性加上 `@api` 装饰器,这样它们才能和 Flow 对接上。 最后说说运行时要注意的几个坑,非常重要。 - 管理员不填值的时候,Flow 传过来的是 `null`,所以你的组件一定要能处理空默认值,别崩了。 - 如果组件被隐藏了,它的输出属性会在导航时被自动设为 `null`。 - 还有,所有输入属性本来默认也是输出属性,这个特性要心里有数。 - 最关键的一点:如果你想在运行时让 Flow 感知到属性变化,比如为了触发反应性和条件可见性,就必须手动触发 `FlowAttributeChangeEvent` 事件,不然 Flow 不会理会你的改动。 记住这几点,你就能顺利地把 Lightning Web Component 接入 Flow 画面了。有什么问题随时问我。

    查看详情
  • 2

    Embed a Flow — Create, Start & Input Variables

    第 344 页

    好,同学们,我们来看一下怎么把一个流程直接嵌入到你的闪电网页组件里。 这个闪电组件,它专门用来在你的页面上运行一个流,就像直接打开流程一样。你只需要给它一个属性,叫做 flow-api-name,这个属性告诉它要运行哪个流。这个值你可以直接写死一个字符串,比如“我的审批流”,也可以用动态的 getter 函数,根据不同的条件来切换不同的流,非常灵活。 接下来,这个组件会触发一个重要的事件,叫 onstatuschange。它会告诉我们这个流现在的生命周期状态是什么。状态一共有六种,比如它刚刚开始、正在运行、暂停、还是已经结束。在事件里,你可以拿到很多有用的信息,比如流运行结束后的输出变量、当前停在哪一个活动阶段,甚至还能访问到一个“面试收件箱”。这样你就能实时跟踪流的运行情况了。 那怎么往流里面传输入变量呢?也很简单。你通过一个 input-variables 属性,它是一个数组,每个数组项是一个对象,包含三个字段:name 是变量名,type 是类型,value 是值。注意哦,不同的流数据类型,在这里要对应到 JavaScript 的类型。比如:文本类型就传字符串,数字就用 JavaScript 的数字,记录类型(我们常说的 SObitch)可以传一个对象,日期类型要写成 yyyy-MM-dd 这种格式的字符串,日期时间则是 ISO 8601 格式的字符串,布尔值就直接用布尔值。 特别提一下记录变量,它可以只传单个字段的值,也可以从 Apex 直接传进一个完整的记录对象,把整个记录塞进去。不过前提是,这个流必须是主动启动的流,而且变量必须开启了“允许输入访问”的选项。还有一点很重要,这些输入值只能在流面试刚开始的时候设置,流跑起来之后是不能再更改的,这一点一定要记住。 另外,如果你在使用闪电网页运行时站点,也就是 LWR 站点,要注意一个限制:如果你的闪电组件里面自己又包了一个自定义的 LWC 或者 Aura 组件,那这个闪电组件就不能用了,它会罢工的。所以在这种站点上,要确保闪电组件内部不要嵌套其他自定义的自定义组件。 好了,关于把流程嵌入 LWC 的知识点就这些,大家结合例子练一练,很快就上手了。

    查看详情
  • 3

    Control Finish Behavior & Resume Paused Interviews

    第 345 页

    好,那我们来谈谈在使用 Lightning Web Components 控制流程时,一个很实用的技巧——怎么处理流程的结束状态,以及怎么恢复一个暂停中的面试。 默认情况下,如果你没有做任何设置,当流程运行结束时,它会自动开启一个全新的面试。这不一定是我们想要的,比如我们想在流程完成后跳转到刚刚创建的那条记录,或者只是显示一条消息。所以,我们需要用一点自定义逻辑来控制。 我们可以使用 flow 组件上的 `onstatuschange` 事件处理程序,来监听流程的状态变化。当状态变成 `FINISHED` 时,我们就可以执行自己的代码了。一个很常见的例子就是导航:从流程的输出变量里提取出新记录的 ID,然后利用 NavigationMixin 重定向到该记录的详情页,这样用户完成流程就能直接看到结果。 另外,如果你用的是自动启动的流,也就是 `auto-start` 的那种,还可能会遇到一个特殊状态叫 `FINISHED_SCREEN`。记得也要处理它,否则屏幕可能会停在那里没反应。 接着是暂停面试的恢复。如果你想帮用户恢复他们之前没填完的流程,可以在组件上设置 `flow-interview-id` 属性,传入那个暂停面试的 ID。但你得先找到这个 ID。怎么做呢?在 Apex 控制器里,我们可以去查 `FlowInterview` 对象,按照当前的用户和流名称来筛选,看看有没有暂停状态的面试记录。如果有,就返回第一个 ID;如果没有,就返回空。然后通过一个 wire 连线把这个数据拿到前端。 在 JavaScript 里,我们可以根据 wire 返回的结果来做分支处理。如果数据为空,或者出了错,说明没有可恢复的面试,那么我们就设置 `flow-api-name` 属性,告诉组件:“开始一个新面试吧”。如果拿到一个暂停面试的 ID,我们就设置 `pausedInterviewId` 变量,并把它绑定到组件的 `flow-interview-id` 属性上,这样就能恢复面试。 这里有个关键的规则一定要记住:,你不能同时设置 `flow-api-name` 和 `flow-interview-id`,,它们两个是互斥的。所以我们才会在模板里用条件判断,要么显示一个,要么显示另一个。这样就能保证流程组件只做一件事——要么开始新的,要么恢复旧的。 通过这样的设计,你就可以很灵活地控制流程的用户体验,既能让用户接着上次的继续填,也能完成后快速跳转到需要的地方。

    查看详情
  • 4

    Reactive Screen Flows — Overview & Standard-to-Standard

    第 346 页

    好,那我们现在来讲一个特别简单、也特别好理解的反应性模式,叫“标准到标准反应性”。 你可以把它想象成——两个都是Salesforce平台自带的Flow组件,它们天生就懂怎么互相聊天,不需要我们写一行代码去“介绍”它们认识。 比如我们有一个文本组件,用户在里面随便打点字,它的输出类型就是个简单的字符串。旁边再放一个“姓名”组件,里面有个“名字”字段,刚好它也接受一个字符串作为输入。你看,一个的输出是字符串,另一个要的刚好也是字符串,这就叫“类型兼容”。 那在Flow Builder里要怎么让它们连起来呢?很简单,你只要打开那个接收数据的组件——也就是姓名组件——它的属性面板里会有一个“反应性”相关的设置。你点进去,从候选列表里直接选那个文本组件就行了。这就相当于告诉Flow:“嘿,这个姓名字段啊,你就跟着那个文本组件走,它变你就跟着变。” 设置好之后,用户在前端界面上一边打字,另一边那个姓名字段就会立刻、实时地更新出来。这个过程是Flow运行时在后台自动帮你处理的,你完全不用操心什么数据绑定或者事件监听。 所以你看,这个模式其实就在用最直观的方式告诉你:“一个组件的输出,直接变成另一个组件的输入,而且这个变化是瞬间就在同一个屏幕里完成的。”这就是反应性最基础、最核心的概念了。 而且因为从头到尾用的全是标准组件,你既不用写HTML、也不用写JavaScript,对新手特别友好。咱们先把这个模式吃透,后面再遇到更复杂的自定义反应性,心里就有个很清晰的参照了。 这样讲是不是就很好懂了?

    查看详情
  • 5

    Reactive Patterns — Standard to Custom & Custom to Standard

    第 347 页

    大家好,今天我们来讲一个小知识点,就是在Flow里面,标准组件和自定义组件之间怎么互相传递数据,让界面能实时反应。这个概念在LWC里叫做“反应性”,其实就是数据变了,界面自动跟着变。 首先,当标准组件要把数据传给自定义组件的时候,我们叫它“标准到自定义反应性”。这时候,自定义组件需要有一个属性,用@api声明,而且这个属性的类型必须和标准组件输出的类型保持一致。举个例子,假如有一个Text组件,它输出一个String类型的颜色名称,我们要把它传给我们自己写的组件。那我就在自定义组件里写一个@api color,这样Flow运行时就会自动把Text的值赋给color属性。然后我在组件里用内联样式,比如 style="color:{color}",就能看到颜色立刻变了。很简单,对吧? 反过来,当自定义组件要主动通知Flow,我里面的值变了,让其他组件都能感知到,这就叫“自定义到标准反应性”。这时候不能只靠@api属性自动扩散,必须手动触发一个事件,叫FlowAttributeChangeEvent。这个事件构造函数接受两个参数:第一个是属性的名字,要和你JS文件里@api声明的名字一模一样,包括大小写;第二个是更新后的新值。你把这个事件派发出去,Flow运行时就会收到通知,把值传给其他绑定在一起的组件。 这里有个关键点要注意:我们要用getter和setter来管理这个@api属性。为什么?因为setter会被调用两次。第一次是当你在组件内部触发FlowAttributeChangeEvent后,Flow会回过头来重新设一次值;第二次是当其他组件改变了绑定到这个属性的值,Flow也会调用这个setter。这种双重调用保证了无论变化是我自己发起的,还是别人传过来的,数据都能更新,界面保持同步。这就是getter/setter模式的重要性。 所以,同学们记住这三个要点:@api属性类型匹配,FlowAttributeChangeEvent主动通知,以及用getter/setter保证双向同步。这样你写的自定义组件就能在Flow里和标准组件完美配合了。

    查看详情
  • 6

    Reactive Pattern — Custom to Custom & Best Practices

    第 348 页

    今天我们来聊聊 Lightning Web Components 里一种特殊的通信方式:,自定义对自定义反应,。这个听起来有点拗口,其实就是让两个独立的组件能够联动——一个发起变化,另一个自动响应。这个能力对于构建在 Flow 里嵌入的组件特别有用。 首先,两个组件都得遵守一个约定,叫做 ,FlowAttributeChangeEvent 契约,。简单说,源组件要负责派发一个事件,里面带上属性名和新值;反应组件则通过 `@api` 标注的属性来接收这个变化。 事件构造的时候,一定要注意:传给构造函数的那两个参数,第一个是,确切的 API 属性名,,第二个是,更新后的值,。这个属性名在你的 JS 文件、`js-meta.html` 配置文件和你用来触发事件时写的字符串,,三处必须完全一致,,一个字母都不能差。值呢,必须跟这个属性声明的数据类型匹配,比如你声明的是数字,就别传字符串。如果你要传一条记录,那就传一个包含字段和值的 ,JSON 对象,。 那在反应组件这边,怎么优雅地处理这个变化呢?最佳实践是,一定用 get/set 模式来包装 `@api` 属性,。因为 setter 有两个触发源:一个是外部 Flow 属性变化,另一个就是我们刚才说的事件触发。不管变化从哪里来,setter 都会执行,这样你就能在里面统一做状态更新,确保组件的逻辑是稳健的。这里要记住一条铁律:,永远不要在组件内部直接修改 `@api` 属性的值,——想改的话,一定要去触发 `FlowAttributeChangeEvent`,让整个流程按规矩走。 还有个小细节:事件对象一旦构造出来,就,别再去改它身上的 `bubbles`、`composed` 这些属性,了,因为它们在 LWC 里是只读的,硬改可能导致未知错误。另外,如果你的组件既要触发导航,又要触发属性变化,一定要留意,别让这两个动作同时飞出去,,否则可能出现竞态条件,让界面变得不可预测。通常的做法是把它们错开执行,或者通过一步回调用异步的方式处理清楚。 总结一下就四步:源头发事件,目标用 setter 接,三处名字要一致,值类型要匹配。这样你的自定义组件就能在 Flow 里如鱼得水,相互反应顺畅无 bug 了。 好了,这块内容就讲到这里,有什么疑问随时提。

    查看详情
  • 7

    State Management & Derived Attributes Best Practices

    第 349 页

    同学们好,今天我们来聊聊 LWC 在 Flow 里面的状态管理,你会发现它和 Aura 有根本性的不同。在 Aura 里,我们可能会直接去改一个属性,但在 LWC 里,这样做就会出问题。 LWC 强制执行非常清晰的所有权分离。一个用 @api 装饰的属性,只能由父级去修改——在 Flow 的场景里,Flow 运行时就是父级。也就是说,Flow 屏幕把值传给组件,是通过 @api 属性进来的。而组件自己内部使用的状态,应该用 @track,或者更简单,直接用没有装饰的普通属性。 当组件内部的状态发生变化,需要告诉 Flow 的时候,我们不能直接去给 @api 属性赋值。正确的做法是触发一个 FlowAttributeChangeEvent 事件,把属性的新值传出去。因为 Flow 运行时需要追踪这些变化,才能维护好界面的反应性,还有条件可见性那些准确的状态。如果你偷偷改了 @api,Flow 就不知道内容变了,界面就会出现各种奇怪的现象。 其实呢,平台还保留了一些向后兼容的行为,比如在导航的时候会提取 @api 属性当前的值。但千万别去依赖这个,这只是过渡期的兜底方案,未来的版本随时可能不支持。 接下来要讲一个非常重要的模式,叫“双位置模式”,专门用来处理派生属性。比如,表单里某个字段的值一改,你要立刻更新一个隐藏的状态。这时候你需要在两个地方触发事件:一是在那个“驾驶属性”的 setter 里,保证每次值变化都能驱动整个反应链;二是在 connectedCallback 生命周期里,这样当组件刚初始化展示的时候,也能基于初始值触发一次更新。两个位置缺一不可。 还有一个很常见的踩坑点:有些人会想用 Promise.resolve().then() 去延迟触发事件,觉得这样可以等一等生命周期。千万不要这么做!这样当用户重新访问这个屏幕的时候,你延迟的事件可能会覆盖掉 Flow 恢复过来的保留值,造成数据错乱。 最后,为了让大家养成好习惯,可以在项目里配上 linter 规则,强制检查“不能直接修改 @api 属性”这个模式。有了工具的提醒,代码就不会不小心写出反模式来。 好了,这节课的重点就是:LWC 把属性所有权分得很清楚,Flow 里的 @api 是只读的,通过事件来通信,记得用双位置模式,别依赖向后兼容,更别用 Promise 去延迟事件。这部分掌握好,Flow 里的组件交互就稳了。

    查看详情
  • 8

    Navigation Events & Component Patterns

    第 350 页

    同学们好,今天我们来聊聊在 Flow 里自定义组件时,如何控制流程的导航,以及两种很实用的数据绑定模式。 先说导航事件。你写的组件放在 Flow 里,用户点击下一步、返回,或者卸载、完成,这些动作其实都需要组件来指挥流程往下走。在 LWC 里,我们专门有一组导航事件,比如 Next、Back、Finish 这些,它们都是从 lightning/stream 这个模块导入的。记好,这些事件只能放在事件处理函数里触发,像 handleClick 这种,绝对不能在生命周期勾子,比如 connectedCallback 里调用,不然会出错。 还有一点特别重要:一旦你调度了导航事件,代码的执行其实是立刻跳转的。也就是说,在 dispatchEvent 之后,不要再写任何代码了,那些代码根本不会执行。你就想象成点击按钮后,这一屏马上切走了,后面任何操作都来不及做。 接下来看颜色选择器模式,这是一个很好的职责分离示范。在这个模式里,组件只对外暴露一个输出值,也就是用 @api 装饰的 color 属性,这个值会传回 Flow。而组件内部的状态,比如用户输入的文本、当前选中的色块编号,统统用没有装饰的普通属性来维护。这样外部只关心最终结果,内部怎么变跟 Flow 无关,结构非常干净。 最后是 salutation 模式,它教我们怎么把多个 @api 输入属性,组合成一个显示值。比如你把称呼、姓名片段这些都作为输入,怎么动态拼出完整的问候语呢?这里没有用 track 去手动更新,而是定义了一个 getter 函数,它会根据所有输入属性,实时计算出派生值。 关键点来了,这种多输入的组件需要防御性编程。因为 Flow 运行时不保证你那些 @api 属性的设置顺序,可能它先设了姓,再设了名称前缀,也可能反过来。所以,我们在每个 @api setter 里面,都要重新触发一次派生逻辑的更新。用 getter 的好处就在这里,因为 getter 每次被访问时都会根据当前所有属性重新计算,无论它们被设置的顺序是什么,最终显示一定是对的。这样你的组件在 Flow 里就非常健壮,再也不会因为属性赋值的先后顺序而显示异常了。 好了,今天这页内容的精华就是这些,导航事件要放在 handler 里触发,触发后别写代码;颜色选择器分清内外状态;salutation 模式利用 getter 和每个 setter 的重新计算来保证多输入顺序无关的正确显示。希望你们能理解并在自己的组件里用起来。

    查看详情