将Lightning Web Components开源转换为Salesforce – 创建一个Salesforce应用

创建一个Salesforce应用

在此步骤中,您将创建一个Salesforce DX项目并构建您的第一个Lightning App。

创建一个Salesforce DX项目

现在已经设置了Salesforce CLI,创建一个新项目并授权您的Trailhead Playground。

  1. 打开命令提示符,例如Windows上的cmd或macOS上的终端。
  2. 使用此命令创建一个新的Salesforce DX项目。
  3. sfdx force:project:create -n lightning-conference
  4. 使用此命令导航到新目录。
  5. cd lightning-conference
  6. 运行以下命令以使用Salesforce CLI授权Trailhead Playground,使用新别名保存它,并将当前用户设置为默认用户:
  7. sfdx auth:web:login -s -a conference
  8. 当带有Salesforce登录页面的浏览器窗口打开时,输入您在上一个项目中记下的Trailhead Playground凭据。

您的Salesforce组织现已获得授权。您可以随时使用以下命令在命令行中的浏览器中将其打开:sfdx force:org:open

创建一个应用页面

Salesforce应用程序是一组选项卡,使用户可以轻松访问一组相关功能。您将迁移在上一个项目中创建的单页Node.js应用程序,并将其转换为Salesforce应用程序。

首先创建一个显示会话列表的议程应用页面。该页面是使用Lightning App Builder(声明性用户界面生成器)创建的。您稍后将使用此工具将组件添加到页面。现在,您只需创建一个空白页。

  1. 通过运行打开Salesforce组织 
    sfdx force:org:open
  2. 从设置中,Lightning App Builder在“快速查找”框中输入并选择Lightning App Builder。
  3. 点击新建
  4. 将默认选择保留到“应用程序页面”,然后单击“下一步”
  5. 输入Agenda作为标签,然后单击 下一步
  6. 选择一个区域作为页面布局,然后单击完成
  7. 点击保存
  8. 点击激活
  9. 保留默认设置,然后单击“保存”,然后单击“完成”
  10. 单击后退左页面,返回到设置上。

该页面需要添加到Lightning App。您尚未创建一个,让我们开始吧。

创建闪电会议应用程序

  1. 在“设置”中,输入App Manager“快速查找”框,然后选择“应用程序管理器”
  2. 单击“新建闪电应用程序”
  3. 如下定义新的Lightning应用程序。
    • 应用名称: Conference
    • 开发者名称: Conference
  4. 单击下一步
  5. 在“应用程序选项”屏幕上,保留默认设置,然后单击“下一步”
  6. 在“实用程序项”屏幕上,保留默认设置,然后单击“下一步”
  7. 在“导航项目”屏幕上,选择“议程会话,然后将其移动到“选定的项目”框中。然后单击“下一步”。议程是我们刚刚创建的应用页面。创建Session对象时,Sessions导航项是在上一个项目中自动创建的。
  8. 在“用户配置文件”屏幕上,选择“系统管理员”,然后将其移至“选定的配置文件”。
  9. 点击保存并完成
  10. 在应用启动器(应用启动器)中,找到并选择会议

应用启动器中的应用。

恭喜你!您刚刚在Salesforce平台上创建了第一个应用程序。这个第一个版本看起来有些空白,因此在下一步中,您将向其中添加自定义组件。

将Lightning Web Components开源转换为Salesforce – 安装Salesforce开发工具

学习目标

在此项目中,您将:

  • 设置您的Salesforce开发人员环境。
  • 创建一个Salesforce DX项目。
  • 将Lightning Web组件转换为Salesforce平台。
  • 使用Apex从Salesforce检索数据。

介绍

在此项目中,您将使用Lightning Web Components Open Source作为Node.js应用程序开发的会议管理应用程序迁移到Salesforce平台。

完成的会议应用程序概述。

您仍将使用Lightning Web组件,但是您将从Salesforce平台在开源框架之上添加的一组强大功能中受益。您将看到在Salesforce上实现组件如何通过声明性配置选项提供更大的灵活性,以及​​如何减少构建应用程序所需的代码量。

在你开始之前

在执行此动手项目中的步骤之前,请确保完成使用Lightning Web Open Source生成第一个应用程序并使用Lightning Web Components Open Source项目访问Salesforce数据。您在此处所做的工作基于这些项目中的概念和所做的工作。

安装命令行界面(CLI)

为了将Lightning Web Components部署到Salesforce平台,您需要安装Salesforce命令行界面(CLI)。Salesforce CLI是一个命令行界面,可在与Salesforce组织一起使用时简化开发。

  1. 使用这些链接安装CLI。
    操作系统 链接到安装程序
    苹果系统 https://sfdc.co/sfdx_cli_osx
    Windows 32位 https://sfdc.co/sfdx_cli_win
    Windows 64位 https://sfdc.co/sfdx_cli_win64
    Debian / Ubuntu 64 https://sfdc.co/sfdx_cli_linux
    从清单中的URL之一下载档案,提取档案,然后运行./install脚本。
    Debian / Ubuntu x86 https://sfdc.co/sfdx_cli_linux_x86
    从清单中的URL之一下载档案,提取档案,然后运行./install脚本。
  2. Salesforce CLI每周更新一次,因此,请确保通过sfdx update在命令窗口中运行来获取最新和最好的信息。
  3. 让我们确保正确安装了CLI,并且您知道如何访问命令的联机帮助。在命令窗口中,输入sfdx

您应该会看到以下内容:

Usage: sfdx COMMAND [command-specific-options]
Help topics, type "sfdx help TOPIC" for more details:
sfdx force # tools for the salesforce developer
sfdx plugins # manage plugins
sfdx update # update sfdx-cli

安装用于Visual Studio Code的Salesforce Extensions

Visual Studio Code是Salesforce开发人员的首选代码编辑器。它是免费的开放源代码,可用于Windows,Linux和macOS。该编辑器具有易于安装的扩展程序,用于语法高亮显示,代码完成等。

选择了Salesforce Extension Pack的Visual Studio代码。

在此项目中,我们将安装Visual Studio Code和推荐的Salesforce Extension Pack。

  1. 下载并为您的操作系统安装最新版本的Visual Studio Code。如果您已经安装了Visual Studio Code,则无需重新安装它。
  2. 启动Visual Studio代码。
  3. 在左侧工具栏上,单击扩展图标 Visual Studio代码的扩展图标
  4. 搜索Salesforce Extension Pack,然后单击Install。如果已经安装它,则只需单击“重新加载”按钮。

搜索栏中显示带有Salesforce Extension Pack的Visual Studio代码。

注意

Salesforce Extensions for Visual Studio Code中的某些功能(尤其是Apex支持)取决于Java平台标准版开发套件(JDK)。仅支持JDK 8和11。如果安装了其他版本的Java,则还需要安装JDK 8或JDK11。一旦安装了正确的JDK,您可以按照此处的步骤配置设置。您无需对SDK进行任何更改即可完成此项目。

既然您已经安装了Visual Studio Code并启用了必要的扩展,则需要对其进行测试。

  1. 在Visual Studio Code中,通过在Windows上按Ctrl + Shift + P或在macOS上按Cmd + Shift + P来打开“命令面板” 。
  2. 输入sfdx以过滤由Salesforce Extensions提供的命令。当您使用更多SFDX命令时,这些命令将显示在最近使用的面板中。

带有SFDX的Visual Studio代码:创建一个默认的便签组织。

不错的工作!您设置了Salesforce开发环境。在下一步中,您将创建一个新项目并开始构建该应用程序。

在闪电Web组件之间通信 – 在不相关的组件之间通信

在不相关的组件之间通信

要在DOM中的子树之间通信(以及在某些情况下,登录到同一组织的不同浏览器窗口之间的通信),请使用闪电消息服务(LMS)。LMS是一项发布和订阅服务,可促进Lightning Web组件,Aura组件和Visualforce页面之间的通信。  

除非您同时控制两个组件和一个公共父组件,否则请使用LMS进行不相关组件之间的通信。LMS功能强大,有效且易于使用,但不要在不必要时诱使您使用它。触发DOM事件效率更高。当您需要与无法控制的父级(例如两个App Builder插槽)在组件之间进行通信时,Lightning消息服务是理想的选择。

LMS通信图显示了一个文档对象,该对象包含多个元素,包括父元素中的一个元素。 LMS通道由元素之间的单向和双向箭头表示。

第三个业务部门希望参与号码处理项目。他们需要“优先计数”和“计数”在自己的组件中在一起,以便可以在需要的地方显示它们。让我们从创建消息通道开始,以便为组件使用做好准备。

名为remoteControl的组件将信息发送到不相关的名为counts的组件。

创建闪电消息通道

  1. 在Visual Studio Code的默认文件夹中,创建一个名为的文件夹 messageChannels
  2. messageChannels文件夹中,创建一个名为的文件 Count_Updated.messageChannel-meta.xml
  3. Count_Updated.messageChannel-meta.xml中,粘贴以下代码:
    <?xml version="1.0" encoding="UTF-8" ?>
    <LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
        <masterLabel>CountUpdated</masterLabel>
        <isExposed>true</isExposed>
        <description>Message Channel to pass Count updates</description>
         <lightningMessageFields>
            <fieldName>operator</fieldName>
            <description>This is the operator type of the manipulation</description>
        </lightningMessageFields>
        <lightningMessageFields>
             <fieldName>constant</fieldName>
            <description>This is the number for the manipulation</description>
         </lightningMessageFields>
    </LightningMessageChannel>
  4. 保存并部署文件。

创建发布者组件

  1. 创建名为的Lightning Web组件remoteControl
  2. 用以下代码替换remoteControl.js的内容:
    import { LightningElement, wire } from 'lwc';
    import { publish, MessageContext } from 'lightning/messageService';
    import COUNT_UPDATED_CHANNEL from '@salesforce/messageChannel/Count_Updated__c';
      
    export default class RemoteControl extends LightningElement {
      
      @wire(MessageContext)
      messageContext;
      
      handleIncrement() {
        // this.counter++;
        const payload = { 
          operator: 'add',
          constant: 1
        };
      
        publish(this.messageContext, COUNT_UPDATED_CHANNEL, payload);
      }
      
      handleDecrement() {
        // this.counter--;
        const payload = { 
          operator: 'subtract',
          constant: 1
        };
      
        publish(this.messageContext, COUNT_UPDATED_CHANNEL, payload);
      }
      
      handleMultiply(event) {
        const factor = event.detail;
         // this.counter *= factor;
        const payload = { 
          operator: 'multiply',
          constant: factor
        };
      
        publish(this.messageContext, COUNT_UPDATED_CHANNEL, payload);
      }
    }

    我们进口publishMessageContext从闪电消息服务。我们还导入刚刚创建的频道(Count_Updated__c)。数据有效载荷与该publish功能一起发送。

  3. 保存文件。
  4. 打开remoteControl.html并在template 标签之间添加以下代码:
      <lightning-card title="Remote Control" icon-name="action:change_record_type">
        <c-controls
          class="slds-show slds-is-relative"
          onadd={handleIncrement}
          onsubtract={handleDecrement}
          onmultiply={handleMultiply}>
        </c-controls>
      </lightning-card>

    注意,我们正在重新使用控件组件。

  5. 保存文件。
  6. 更新remoteControl.js-meta.xml,以使remoteControl组件在Lightning应用程序页面上可用:
        <isExposed>true</isExposed>
        <targets>
            <target>lightning__AppPage</target>
        </targets>
  7. 保存文件。

创建订户组件

  1. 创建名为的Lightning Web组件counts
  2. 用以下代码替换counts.js的内容:
    import { LightningElement, wire } from 'lwc';
    import { subscribe, MessageContext } from 'lightning/messageService';
    import COUNT_UPDATED_CHANNEL from '@salesforce/messageChannel/Count_Updated__c';
      
    export default class Counts extends LightningElement {
      subscription = null;
      priorCount = 0;
      counter = 0;
      
      @wire(MessageContext)
      messageContext;
      
      subscribeToMessageChannel() {
        this.subscription = subscribe(
          this.messageContext,
          COUNT_UPDATED_CHANNEL,
          (message) => this.handleMessage(message)
        );
      }
      
      handleMessage(message) {
        this.priorCount = this.counter;
        if(message.operator == 'add') {
          this.counter += message.constant;
        }else if(message.operator == 'subtract') {
          this.counter -= message.constant;
        } else {
          this.counter *= message.constant;
        }
      }
      
      connectedCallback() {
        this.subscribeToMessageChannel();
      }
    }

    @wire(MessageContext)确保unsubscribe在组件销毁生命周期内运行。

  3. 保存文件。
  4. 打开counts.html并在template标签之间添加以下代码:
      <lightning-card title="Counts" icon-name="action:change_record_type">
        <p class="slds-text-align_center slds-var-m-vertical_medium">
          Prior Count: <lightning-formatted-number value={priorCount}></lightning-formatted-number>
        </p>
        <p class="slds-text-align_center slds-var-m-vertical_medium">
          Count: <lightning-formatted-number value={counter}></lightning-formatted-number>
        </p>
      </lightning-card>
  5. 保存文件。
  6. 更新counts.js-meta.xml,以使计数组件在Lightning应用程序页面中可用:
        <isExposed>true</isExposed>
        <targets>
            <target>lightning__AppPage</target>
        </targets>
  7. 保存文件。

将新组件添加到Event Comms App

  1. 部署lwc文件夹,然后刷新Event Comms应用程序页面。
  2. 打开事件通讯页面进行编辑。
  3. remoteControl组件拖到页面的右侧区域。
  4. counts组件拖到remoteControl组件下方的右侧区域。
  5. 单击“保存”,然后退出Lightning App Builder。

验证通讯

  1. 单击远程控制中的按钮以更改计数组件中的计数。

您也可以使用Lightning消息服务与Aura组件和Visualforce页面进行通信。这是使不同类型的组件保持同步的最干净的方法。 

现在,您已经掌握了有关如何在Lightning Web组件之间进行通信的知识。您研究了子对父,父子对以及不相关的组件方案。确保检查资源以了解有关与Lightning Web组件通信的更多信息。

在闪电Web组件之间通信 – 父母与孩子沟通

父母与孩子沟通

为了启用从父组件到子组件的通信,子组件公开一个属性或函数以使其公开。然后,父母可以更新孩子的公共财产或调用孩子的公共职能。

父母与孩子之间的通信图,显示了增幅器至分子。

此外,如果要添加一些功能,请在子组件上将public属性更新为getter和setter。

让我们从简单的公共属性更新开始。另一个业务部门找到了您构建的分子。他们想使用它并添加到它。他们的第一个要求是能够设置计数器的起始编号。我们不想进行任何会影响原始业务用例的更改,因此让我们将分子组件包装在另一个组件中,该组件将拥有新功能。 

更新公共财产

@api子组件中的装饰器公开一个属性,使其公开,以便父组件可以对其进行更新。

  1. 在子组件(分子)中公开一个公共属性:
    1. 在Visual Studio Code中,打开numerator.js并将@api 装饰器应用于counter属性:
        @api counter = 0;
    2. apilwc模块导入装饰器。
    3. 保存文件。
  2. 创建并编写一个名为的新父组件augmentor
    1. 创建名为的Lightning Web组件augmentor
    2. extraor.js中,将此代码粘贴到Augmentor类中:
        startCounter = 0;
        
        handleStartChange(event) {
          this.startCounter = parseInt(event.target.value);
        }
    3. 保存文件。
    4. 打开exporor.html,并在template标签之间添加以下代码 :
        <lightning-card title="Augmentor" icon-name="action:download">
          <lightning-layout>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <lightning-input
                label="Set Starting Counter"
                type="number"
                min="0"
                max="1000000"
                value={startCounter}
                onchange={handleStartChange}>
              </lightning-input>
            </lightning-layout-item>
          </lightning-layout>
          <c-numerator
            class="slds-show slds-is-relative"
            counter={startCounter}>
          </c-numerator>
        </lightning-card>
    5. 保存文件。
    6. 更新exporor.js-meta.xml,以在Lightning应用程序页面上使增强器组件可用:
          <isExposed>true</isExposed>
          <targets>
            <target>lightning__AppPage</target>
          </targets>
    7. 保存文件。
  3. 将新组件(增强器)添加到Event Comms应用程序页面:
    1. 部署lwc文件夹,然后刷新Event Comms应用程序页面。
    2. 打开Event Comms应用页面进行编辑。
    3. 扩充器组件拖到页面的中央区域。
    4. 单击“保存”,然后退出Lightning App Builder。
  4. 验证通讯:
    1. 要查看Salesforce中的更改,请刷新Event Comms应用程序页面。
    2. 在设置起始计数器字段中输入数字。
      计数将更新为您输入的内容。
    3. 单击乘法按钮之一。
      请注意,计数器会更新,但“设置起始计数器”保持不变。
    4. 更改原始分子组件中的值。
      它继续按预期工作。

父组件(增强器)将信息(startCounter)发送到子组件(分子)中的计数器属性。

因为我们将“设置起始计数器”放在其自己的组件(增强器)中,所以没有将其添加到分子组件中,而是继续为原始业务案例提供服务。现在分子从子级(控件)和父级(增强器)接收输入。

调用公共功能

该业务的第二个请求是将总数增加一百万。他们不希望设置开始计数发生变化。这意味着我们不能只更新startCounter属性。我们也没有要添加的扩充器组件中的当前计数。我们将对孩子调用一个公共函数来为我们进行更新。

@api子组件中的装饰器公开一个函数,使其公开,以便父组件可以调用它。

  1. 在子组件(分子)中创建一个公共函数:
    1. 打开numerator.js并将此maximizeCounter函数添加到该函数之后handleMultiply
        @api
        maximizeCounter() {
          this.counter += 1000000;
        }
    2. 保存文件。
  2. 在父组件(增强器)中,添加一个按钮及其处理程序:
    1. 打开exporor.js,并在handleMaximizeCounter 函数后添加以下handleStartChange函数:
        handleMaximizeCounter() {
          this.template.querySelector('c-numerator').maximizeCounter();
        }

      该函数c-numerator在exporor.html中找到标签并调用公共maximizeCounter函数。

    2. 保存文件。
    3. 打开exporor.html,并将其添加lightning-button到Set Starting Counter之后lightning-input
              <lightning-button 
                class="slds-var-p-vertical_xx-small"
                label="Add 1m To Counter"
                onclick={handleMaximizeCounter}>
              </lightning-button>
    4. 保存文件。
  3. 验证通讯:
    1. 要查看Salesforce中的更改,请部署lwc文件夹,然后刷新Event Comms应用程序页面。
    2. 单击“添加1m到计数器”
      数量增加了一百万。

在父级(增强器)中,新按钮触发handleMaximizeCounter 处理程序,该处理程序调用子级组件(分子)并触发其公共 maximizeCounter功能。

与前面的描述相对应的图。

使用公共Getter和Setter

此练习与在此步骤开始时更新属性的方式非常相似。实际上,我们根本不会更改父组件。在子组件中,我们仅使用公共获取器和设置器来实现公共柜台属性。

使用Event Comms的两个业务部门都喜欢更新。现在他们希望随着计数的变化看到计数的先前值。每当更改计数器属性时,我们都需要一种方法来捕获当前计数。在设置新值之前,我们可以获取当前计数并保存它。让我们使用一个名为的新私有变量,_currentCount以便我们可以使用它。为了保存先前的计数以便我们可以显示它,我们将使用一个名为的变量 priorCount

对于其他功能,我们将该counter属性实现为getter和setter(getset,也称为访问器属性)。然后,每次设置计数器时,我们都会在设置新的计数器值之前将当前计数器值(_currentCount)存储在priorCount变量中。

  1. 向子组件(分子)添加一个先验计数:
    1. 打开numerator.html并将此段落添加到带有Count的段落之前:
            <p class="slds-text-align_center slds-var-m-vertical_medium">
              Prior Count: <lightning-formatted-number value={priorCount}></lightning-formatted-number>
            </p>
    2. 保存文件。
    3. 打开numerator.js并进行@api counter = 0;注释(添加//到该行的开头)。
    4. 在评论之后,添加以下代码:
        _currentCount = 0;
        priorCount = 0;
        
        @api
        get counter() {
          return this._currentCount;
        }
        set counter(value) {
          this.priorCount = this._currentCount;
          this._currentCount = value;
        }

      此代码counter使用getter(get)和setter(set)函数更改为属性。它还添加priorCount和 _currentCount属性。

    5. 保存文件。
  2. 验证通讯:
    1. 要查看Salesforce中的更改,请部署lwc文件夹,然后刷新Event Comms应用程序页面。
    2. 单击“添加”,“ X2 ”和“向计数器添加1m” 以更改计数器值。
      更新计数器时,Prior Counter保持同步。
    3. 单击Numerator和Augmentor组件中的按钮以查看原始功能不受影响。

我们更新了分子组件,以使用getter和setter来更新新 priorCount属性。父组件(增强器)仍将信息(startCounter)发送到子组件(分子)。但现在,分子使用getter和setter来get_currentCount财产,set 在_currentCountpriorCount属性。

与前面的描述相对应的图。

挑战自己(可选-我们将不检查此代码)
更新handleMaximizeCountermaximizeCounter接受一个参数,该参数指定要添加到计数中的数字。提示:回顾你在步骤1中所做的发送 data-factormultiply自定义事件。

概要

您已经解决了Lightning Web组件之间的子对父和父子对子通信。在下一步中,您将使用Lightning消息服务在没有父子关系的组件之间进行通信。

在闪电Web组件之间通信 – 从孩子到父母沟通

学习目标

在此项目中,您将:

  • 构建彼此通信的Lightning Web组件。
  • 从子组件与其父组件进行通信。
  • 从父组件与子组件进行通信。
  • 从组件通信到不相关的组件。

该项目是为具有一定的Lightning Web组件经验的Salesforce开发人员设计的。如果您还不熟悉Lightning Web组件,我们建议您 在继续进行此项目之前,先完成Build Lightning Web Components路径中的一些标志 。

组件如何通信

当多个Lightning Web组件组成一个应用程序时,我们通常希望这些组件共享信息。我们如何从一个组件传递到另一组件取决于组件是否相关以及如何关联。另一个组件内部的组件将创建父子关系。父母与孩子交流的方式与孩子与父母交流的方式不同。这些都与不相关的组件(独立的DOM子树中的组件)相互通信的方式不同。

通讯类型:子对父,父子对以及不相关的组件。

在这个项目中,您将在每个关系中的组件之间建立通信。 

在你开始之前

我们假设您已经设置了Salesforce DX开发环境,并且可以轻松地使用它来创建Lightning Web组件并将其部署到组织中。如果您还不熟悉此过程,请先完成“ 快速入门:闪电Web组件” 项目,然后再继续进行此项目。

创建一个新的Trailhead游乐场

对于此项目,您需要创建一个新的Trailhead Playground。滚动到该页面的底部,单击游乐场名称,然后单击创建Trailhead游乐场。创建新的Trailhead游乐场通常需要3-4分钟。 

注意:是的,我们的意思是全新的Trailhead游乐场!如果您使用现有的组织或游乐场,则可能会遇到无法完成挑战的问题。

获取您的Trailhead Playground用户名和密码

让我们开始吧。转到您的Trailhead游乐场。(如果尚未打开,请滚动至该页面的底部,然后单击启动。)如果您在组织中看到一个标签为Get Your Login Credentials的标签,太好了!跳至步骤1。否则,请从App Launcher(应用启动器)中找到并打开Playground Starter,然后按照以下步骤操作。

  1. 单击获取您的登录凭据选项卡,并记下您的用户名。 
  2. 单击重置我的密码。这会将电子邮件发送到与您的用户名关联的地址。
  3. 单击电子邮件中的链接。
  4. 输入新密码,确认,然后单击更改密码。

设置项目

  1. 在Visual Studio Code中,创建一个名为的Salesforce DX项目Event Comms
  2. 授权您的Trailhead游乐场。

与自定义事件进行交流

让我们从一个简单的场景开始。子组件调度一个自定义事件,该事件触发父组件中的更新。

一个名为controls的子组件包含在其父组件(分子组件)中并与其通信。

发送事件时,您可以选择发送一些数据,并允许事件在DOM中冒泡。让我们从一个简单的场景开始。子组件调度一个自定义事件,该事件触发父组件中的更新。

从控件组件传递到分子组件

  1. 创建一个名为三个区域的Lightning应用程序页面Event Comms
    1. 在您的组织(您的Trailhead游乐场)中,打开“设置”。
    2. 在“快速查找”框中,输入Lightning App Builder,然后选择Lightning App Builder
    3. 点击新建
    4. 选择“应用程序页面”后,单击“下一步”
    5. 对于标签,输入Event Comms,然后单击下一步
    6. 选择三个区域,然后单击完成
    7. 单击保存激活保存完成
    8. 单击背部 以退出Lightning App Builder。
  2. 创建名为的父Lightning Web组件numerator
    1. 在Visual Studio Code中的force-app / main / default下,右键单击 lwc文件夹,然后选择SFDX:Create Lightning Web Component
    2. 输入numerator新组件的名称。
    3. Enter,然后再次按Enter接受默认值force-app/main/default/lwc
  3. 编写分子组件文件的代码:
    1. numerator.js中,将此代码粘贴到Numerator类中:
        counter = 0;
        
        handleIncrement() {
          this.counter++;
        }
        handleDecrement() {
          this.counter--;
        }
    2. 保存文件。
    3. 打开numerator.html,并在template标签之间添加以下代码 :
        <lightning-card title="Numerator" icon-name="action:manage_perm_sets">    
          <p class="slds-text-align_center slds-var-m-vertical_medium">
            Count: <lightning-formatted-number value={counter}></lightning-formatted-number>
          </p>
          <!-- controls go here -->
        </lightning-card>
    4. 保存文件。
    5. 要使分子组件在Lightning应用程序页面中可用,请打开 numerator.js-meta.xmlisExposed 用以下行替换标记:
          <isExposed>true</isExposed>
          <targets>
            <target>lightning__AppPage</target>
          </targets>
    6. 保存文件。
  4. 将分子组件添加到Event Comms应用程序:
    1. 右键单击lwc文件夹,然后选择 SFDX:将源部署到组织将lwc文件夹部署到您的组织。
    2. 应用启动器在您操场上的App Launcher()中,找到并打开Event Comms
    3. 单击 设定 并选择编辑页面以打开Event Comms应用程序页面进行编辑。
    4. 分子组件(在“组件”列表中的“自定义”下)拖到页面的左侧区域。
    5. 点击保存
    6. 单击背部 以退出Lightning App Builder。
  5. 创建并编写名为的子组件controls
    1. 返回Visual Studio Code并创建一个名为的Lightning Web组件 controls
    2. controls.js中,将此代码粘贴到Controls类中:
        handleAdd() {
          this.dispatchEvent(new CustomEvent('add'));
        }
        handleSubtract() {
          this.dispatchEvent(new CustomEvent('subtract'));
        }
    3. 保存文件。
    4. 打开controls.html,并在template标签之间添加以下代码 :
        <lightning-card title="Controls" icon-name="action:upload">
          <lightning-layout>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <lightning-button
                label="Subtract"
                icon-name="utility:dash"
                onclick={handleSubtract}>
              </lightning-button>
            </lightning-layout-item>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <!-- buttons go here -->
            </lightning-layout-item>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <lightning-button
                label="Add"
                icon-name="utility:add"
                onclick={handleAdd}
                icon-position="right">
              </lightning-button>
            </lightning-layout-item>
          </lightning-layout>
        </lightning-card>
    5. 保存文件。
  6. 将子组件(控件)添加到父组件(分子):
    1. 打开numerator.htmlcontrols go here用以下代码替换 注释:
          <c-controls
            class="slds-show slds-is-relative"
            onadd={handleIncrement}
            onsubtract={handleDecrement}>
          </c-controls>
    2. 保存文件。
  7. 验证通讯:
    1. 要查看Salesforce中的更改,请部署lwc文件夹,然后刷新Trailhead Playground组织中的Event Comms应用程序页面。
    2. 单击添加,然后查看计数增加。
    3. 单击以查看计数减少。

现在,我们有了一个子组件(控件),add该组件将事件发送到父组件(分子),从而触发父组件(分子)中的handleIncrement函数。

与前面的描述相对应的图。

使用自定义事件发送数据

接下来,让孩子将带有事件的一些数据传递给父母。该企业希望增加数量。我们将为他们提供多种选择。使用自定义事件将数据从子级传递到父级。

  1. 向子组件(控件)添加乘法按钮和乘法功能:
    1. 打开controls.html,并使用以下代码替换buttons go here 第二个lightning-layout-item标签内的注释:
            <lightning-button
              label="2"
              data-factor="2"
              icon-name="utility:close"
              onclick={handleMultiply}>
            </lightning-button>
            <lightning-button
              label="3"
              data-factor="3"
              icon-name="utility:close"
              onclick={handleMultiply}>
            </lightning-button>
    2. 保存文件。
    3. 打开controls.js,并在handleMultiply 函数后添加以下handleSubtract函数:
        handleMultiply(event) {
          const factor = event.target.dataset.factor;
          this.dispatchEvent(new CustomEvent('multiply', {
            detail: factor
          }));
        }

      注意,我们将onclick事件传递给handleMultiply函数,函数data-factor通过 来获取按钮event.target.dataset.factor。然后,将factor以及新的自定义事件(multiply)传递给父组件(分子)。

    4. 保存文件。
  2. 更新父组件(分子):
    1. 打开numerator.html并将此属性添加到 c-controls标记中:
      onmultiply={handleMultiply}
    2. 保存文件。
    3. 打开numerator.js并将此handleMultiply 函数添加到该函数之后handleDecrement
        handleMultiply(event) {
          const factor = event.detail;
          this.counter *= factor;
        }

      此处,handleMultiply函数获取onmultiply 传入的事件,并使用其数据(event.detail)更新计数(计数器)。

    4. 保存文件。
  3. 验证通讯:
    1. 要查看Salesforce中的更改,请部署lwc文件夹,然后刷新Event Comms应用程序。
    2. 单击添加,然后查看计数增加。
    3. 单击X 2以查看计数乘以2。
    4. 单击X 3以查看计数乘以3。

控件组件将数据(data-factor)以及multiply自定义事件传递到其父级(分子)。

与前面的描述相对应的图。

允许自定义事件冒泡

两个乘法按钮成功了。现在,企业需要更多的乘法选择。让我们轻松添加所需数量的按钮。我们将为按钮添加另一个Lightning Web组件。为了使通信顺利进行,您将使用事件冒泡。冒泡允许来自按钮组件的自定义事件冒泡DOM树。

  1. 创建一个名为的组件button
    1. 创建名为的Lightning Web组件button
    2. button.js中,将此代码粘贴到Button类中:
        @api label;
        @api icon;
        
        handleButton(event) {
          this.dispatchEvent(new CustomEvent('buttonclick',{
            // bubbles: true
          }));
        }
    3. apilwc模块导入装饰器。
      import { LightningElement, api } from 'lwc';
    4. 保存文件。
    5. 打开button.html并在template标签之间添加以下代码 :
        <lightning-button
          label={label}
          data-factor={label}
          icon-name={icon}
          onclick={handleButton}>
        </lightning-button>
    6. 保存文件。
  2. 使按钮组件成为控件组件的子组件:
    1. 打开controls.html并删除 lightning-layout-item包含两个 lightning-button标签的。
    2. 替换为以下代码:
          <lightning-layout-item flexibility="auto" padding="around-small" onbuttonclick={handleMultiply}>
            <template for:each={factors} for:item="factor">
              <c-button
                key={factor}
                label={factor}
                data-factor={factor}
                icon="utility:close">
              </c-button>
            </template>
          </lightning-layout-item>

      请注意,我们已将handleMultiply函数调用移至中的 onbuttonclick处理程序lightning-layout-item。这样可以避免在每个按钮上添加处理程序,从而使代码更干净,更快。

    3. 保存文件。
    4. 打开controls.js并将此factors属性添加到 Controls类中:
        factors = [0,2,3,4,5,6];
    5. 保存文件。
  3. 验证通讯:
    1. 要查看Salesforce中的更改,请部署lwc文件夹,然后刷新Event Comms应用程序页面。
    2. 单击添加,然后查看计数增加。 
    3. 单击X 2,请注意没有任何反应。为什么?默认情况下,自定义事件不会在派发该事件的组件上冒泡。
      自定义事件未通过其容器。
      为使事件(buttonclick)上升到 lightning-layout-item,我们bubbles: true在中 添加CustomEvent
    4. 打开button.js并取消注释(删除//之前的内容) bubbles: true
      现在,自定义事件冒起了它的容器。
    5. 保存文件并再次部署。
    6. 刷新事件通讯应用程序页面。
    7. 现在单击添加将计数设置为1。
    8. 单击X 2以查看计数乘以2。
    9. 单击X 6以查看计数乘以6。
    10. 单击X 0将计数重置为零。
    11. 尝试以下单击:添加X 2X 5, X 2添加X 2。或者:添加, X 3X 2X 2, X 2X 2。或尝试您自己的组合。

挑战自己(可选-我们将不检查此代码)
在控件组件中添加按钮组件的第二个实例,以创建显示在分子组件中的除法按钮。

使用Lightning Web组件构建Bear-tracking应用程序 – 与整个应用程序中的组件进行通信

更新Bear List组件

公园护林员对您有最后要求。他们希望在过滤熊名单时在地图上找到熊。您必须创建一个熊图组件并修改熊列表,以便将事件发送到地图。让我们从更新熊列表开始。

  1. 编辑bearList.js文件。
  2. 在下面添加以下代码import { NavigationMixin } from 'lightning/navigation';
    import { publish, MessageContext } from 'lightning/messageService';
    import BEAR_LIST_UPDATE_MESSAGE from '@salesforce/messageChannel/BearListUpdate__c';

    首次导入从Lightning Messaging Service(LMS)带来实用程序 。此服务使您可以通过Lightning消息通道跨Lightning页面中的兄弟组件发布消息。
    第二个导入是从GitHub检索的基础项目中包含的Lightning消息通道。

  3. 替换这两行…
    @wire(searchBears, {searchTerm: '$searchTerm'})
    bears;

    …具有以下代码:

    bears;
    @wire(MessageContext) messageContext;
    @wire(searchBears, {searchTerm: '$searchTerm'})
    loadBears(result) {
      this.bears = result;
      if (result.data) {
        const message = {
          bears: result.data
        };
        publish(this.messageContext, BEAR_LIST_UPDATE_MESSAGE, message);
      }
    }

    代码重点:

    • 我们检索闪电消息上下文并将其存储在messageContext属性中。
    • 我们使用有线功能捕获传入的熊名单数据,并BearListUpdate__c使用熊记录列表触发自定义Ligthning消息。
    • 我们将searchTerm动态参数传递给有线searchBears适配器,以便每次searchTerm更改时loadBears都会重新执行,并使用新的搜索结果触发一条新消息。
    • 我们使用publish从LMS导入的功能来触发BearListUpdate__c带有清单的Ligthning消息。

创建Bear Map组件

  1. 在VS Code中,右键单击lwc文件夹,然后单击SFDX:Create Lightning Web Component
  2. 命名组件bearMap
  3. 编辑bearMap.js-meta.xml文件,并替换<isExposed>false</isExposed>为这些行。
    <isExposed>true</isExposed>
    <targets>
    	<target>lightning__AppPage</target>
    	<target>lightning__RecordPage</target>
    	<target>lightning__HomePage</target>
    </targets>

    这使您的组件可以放置在任何类型的页面上。

  4. 将以下内容替换为bearMap.html
    <template>
    	<article class="slds-card">
    		<lightning-map
    			map-markers={mapMarkers}
    			zoom-level="11"
    			markers-title="Bears">
    		</lightning-map>
    	</article>
    </template>

    代码重点:

    • 我们显示一个包含地图的卡组件。
    • 该地图显示mapMarkers数组中的项目。
  5. 将以下内容替换为bearMap.js
    import { LightningElement, wire } from 'lwc';
    import { subscribe, unsubscribe, MessageContext } from 'lightning/messageService';
    import BEAR_LIST_UPDATE_MESSAGE from '@salesforce/messageChannel/BearListUpdate__c';
    export default class BearMap extends LightningElement {
      mapMarkers = [];
      subscription = null;
      @wire(MessageContext)
      messageContext;
      connectedCallback() {
        // Subscribe to BearListUpdate__c message
        this.subscription = subscribe(
            this.messageContext,
            BEAR_LIST_UPDATE_MESSAGE,
            (message) => {
                this.handleBearListUpdate(message);
            });
      }
      disconnectedCallback() {
        // Unsubscribe from BearListUpdate__c message
        unsubscribe(this.subscription);
        this.subscription = null;
      }
      handleBearListUpdate(message) {
        this.mapMarkers = message.bears.map(bear => {
          const Latitude = bear.Location__Latitude__s;
          const Longitude = bear.Location__Longitude__s;
          return {
            location: { Latitude, Longitude },
            title: bear.Name,
            description: `Coords: ${Latitude}, ${Longitude}`,
            icon: 'utility:animal_and_nature'
          };
        });
      }
    }

    代码重点:

    • 我们实现了两个组件生命周期挂钩函数:connectedCallbackdisconnectedCallback。组件加载和卸载时会自动调用它们。我们使用这两个功能来订阅和取消订阅我们的自定义BearListUpdate__c闪电消息。
    • 一旦收到BearListUpdate__c消息,该handleBearListUpdate函数就会被调用,并带有当前已过滤的熊记录列表。handleBearListUpdate构建一个地图标记列表,该列表将传递给该mapMarkers属性,然后显示在我们的地图组件上。
  6. 将更新的代码部署到组织。右键单击默认文件夹,然后单击SFDX:将源部署到组织

将Bear Map组件添加到App主页

让我们将新组件添加到应用程序主页。

  1. 在您的组织中,从App Launcher( 应用启动器)中找到并选择Ursus Park。
  2. 单击设置( 安装装置),然后选择编辑页面
  3. 在“自定义组件”下,找到您的bearMap组件并将其拖动到页面的右上角。
  4. 单击“保存返回”以返回主页,并在过滤熊名单时检查地图是否会自动更新。

熊图显示已过滤的熊记录

项目总结

这是一个包装。现在,由于您的努力,公园护林员可以轻松追踪熊。

在整个项目中,您已经使用了Lightning Web Components的所有核心概念:数据绑定,表达式,条件渲染,命令式和有线Apex,组件组成以及组件间事件。

通过Lightning Web Components构建自己的灵活应用程序,从而充分利用这些知识。祝您编码愉快!

使用Lightning Web组件构建Bear-tracking应用程序 – 创建一个子组件并与之交互

创建一个子组件并与之交互

在前面的步骤中,我们的代码库有所增加。现在,花一点时间将我们的清单列表组件重构为几个较小的组件。我们将把熊牌的代码移到一个新的组件中。

创建Bear Tile组件

  1. 在VS Code中,右键单击该lwc文件夹,然后单击SFDX:Create Lightning Web Component
  2. 命名组件bearTile
  3. 打开bearList.html并剪切<!-- Start bear tile -->和之间的所有代码<!-- End bear tile -->
  4. 将代码粘贴到的template标签中bearTile.html。完成后,bearTile.html应如下所示。
    <template>
    	<lightning-card title={bear.Name} class="bear-tile">
    		<div class="slds-var-p-horizontal_small bear-tile-body">
    			<div class="slds-media">
    				<div class="slds-media__figure">
    					<img src={appResources.bearSilhouette} alt="Bear profile" class="bear-silhouette"/>
    				</div>
    				<div class="slds-media__body">
    					<p class="slds-var-m-bottom_xx-small">{bear.Sex__c}</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Age__c} years old</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Height__c} cm</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Weight__c} Kg</p>
    				</div>
    			</div>
    		</div>
    	</lightning-card>
    </template>
  5. 将以下内容替换为bearTile.js
    import { LightningElement, api } from 'lwc';
    import ursusResources from '@salesforce/resourceUrl/ursus_park';
    export default class BearTile extends LightningElement {
    	@api bear;
    	appResources = {
    		bearSilhouette: `${ursusResources}/img/standing-bear-silhouette.png`,
    	};
    }

    我们添加了一个bear装饰有的属性@api。这会将bear属性公开给任何父组件。

  6. 删除bearList.css
  7. bearTile.cssbearTile目录中创建一个新文件,并将以下代码粘贴到该文件中。
    .bear-tile {
      border: 1px solid #d2955d;
      background-color: #fae8d2;
      border-radius: .25rem;
      display: block;
    }
    .bear-silhouette {
      height: 100px;
    }
    .bear-tile-body {
      background: linear-gradient(180deg, rgba(255,255,255,1) 80%, #fae8d2 100%);
    }
  8. 打开bearList.html并更换<!-- Start bear tile --><!-- End bear tile -->与评论<c-bear-tile bear={bear}></c-bear-tile>。一旦完成,bearList.html 应该看起来像这样。
    <template>
    	<lightning-card title="Bears" icon-name="utility:animal_and_nature">
    		<div class="slds-card__body_inner">
    			<!-- Start bear list -->
    			<template if:true={bears.data}>
    				<lightning-input type="search"
    					onchange={handleSearchTermChange}
    					variant="label-hidden"
    					class="slds-var-m-bottom_small"
    					label="Search"
    					placeholder="Search for bears"
    					value={searchTerm}>
    				</lightning-input>
    				<lightning-layout multiple-rows="true" pull-to-boundary="small">
    					<template for:each={bears.data} for:item="bear">
    						<lightning-layout-item key={bear.Id} size="3" class="slds-var-p-around_x-small">
    							<c-bear-tile bear={bear}></c-bear-tile>
    						</lightning-layout-item>
    					</template>
    				</lightning-layout>
    				<!-- No bears found -->
    				<template if:false={hasResults}>
    					<div class="slds-align_absolute-center slds-var-m-vertical_small">
    						This is beary disturbing, we did not find results...
    					</div>
    				</template>
    			</template>
    			<!-- End bear list -->
    			<!-- Data failed to load -->
    			<template if:true={bears.error}>
    				<div class="slds-text-color_error">
    					An error occurred while loading the bear list
    				</div>
    			</template>
    		</div>
    	</lightning-card>
    </template>

    bear将使用我们在前面的步骤中定义的属性引用我们的Bear Tile组件。请注意,我们的组件文件夹和文件已命名bearTile,但我们添加的标签是c-bear-tile。开头c代表默认名称空间,在名称空间后附加小写字母,并用破折号分隔以前的大写字母。

  9. 将更新的代码部署到组织中并测试您的新列表组件。细微的渐变看起来应该更好。

Ursus Park主页上具有自定义样式的熊列表

与Bear List组件进行交互

游骑兵要求能够快速查看熊记录并对其进行编辑,而不必离开主页。让我们单击熊形图块,然后打开一个可编辑的熊形记录表格。

  1. 编辑bearTile.html以下代码并将其添加到<lightning-card title={bear.Name} class="bear-tile">标签之后。
    <div slot="actions">
    	<lightning-button-icon
    		icon-name="utility:search"
    		icon-class="bear-tile-button"
    		variant="bare"
    		alternative-text="Open record"
    		onclick={handleOpenRecordClick}>
    	</lightning-button-icon>
    </div>

    我们添加了一个触发该handleOpenRecordClick功能的编辑按钮。使用actions插槽将按钮放置在闪电卡上。插槽是父组件传递到组件主体的标记的占位符。

  2. bearTile.js在最后一个括号之前编辑并添加以下功能。
    handleOpenRecordClick() {
    	const selectEvent = new CustomEvent('bearview', {
    		detail: this.bear.Id
    	});
    	this.dispatchEvent(selectEvent);
    }

    代码重点:

    • handleOpenRecordClick当用户单击熊图块的打开记录按钮时,将调用该函数。
    • 该函数创建并触发一个bearview包含熊记录ID的自定义事件。
  3. 编辑属性bearList.html并将其添加onbearview={handleBearView}c-bear-tile标签。这使我们能够捕获bearview由tile组件触发的事件。该事件在handleBearView函数中处理。
    <c-bear-tile bear={bear} onbearview={handleBearView}></c-bear-tile>
  4. 将以下内容替换为bearList.js
    import { NavigationMixin } from 'lightning/navigation';
    import { LightningElement, wire } from 'lwc';
    /** BearController.searchBears(searchTerm) Apex method */
    import searchBears from '@salesforce/apex/BearController.searchBears';
    export default class BearList extends NavigationMixin(LightningElement) {
    	searchTerm = '';
    	@wire(searchBears, {searchTerm: '$searchTerm'})
    	bears;
    	handleSearchTermChange(event) {
    		// Debouncing this method: do not update the reactive property as
    		// long as this function is being called within a delay of 300 ms.
    		// This is to avoid a very large number of Apex method calls.
    		window.clearTimeout(this.delayTimeout);
    		const searchTerm = event.target.value;
    		// eslint-disable-next-line @lwc/lwc/no-async-operation
    		this.delayTimeout = setTimeout(() => {
    			this.searchTerm = searchTerm;
    		}, 300);
    	}
    	get hasResults() {
    		return (this.bears.data.length > 0);
    	}
    	handleBearView(event) {
    		// Get bear record id from bearview event
    		const bearId = event.detail;
    		// Navigate to bear record page
    		this[NavigationMixin.Navigate]({
    			type: 'standard__recordPage',
    			attributes: {
    				recordId: bearId,
    				objectApiName: 'Bear__c',
    				actionName: 'view',
    			},
    		});
    	}
    }

    代码重点:

    • 我们导入一个导航mixin,它捆绑了处理导航的实用程序功能。使用mixin,我们可以在不扩展类的情况下向其添加功能。当一个类已经扩展了一个父类(一个类只能扩展一个父类)时,这很有用。
    • 我们的课程将导航混入扩展到了LightningElement基础类。
    • 我们bearviewhandleBearView函数中处理事件。我们从事件详细信息中提取熊记录ID,并使用导航mixin导航到熊记录页面。
  5. 将更新的代码部署到组织中,并测试您是否可以使用图块上的按钮图标导航到熊记录。

这就是步骤。我们已经将组件重构为两个较小的组件:Bear列表和Bear Tile。我们探索了如何使用@api装饰器从父列表组件与子磁贴组件进行通信。我们还看到了如何通过自定义事件从孩子与父母进行交流。

在下一步中,我们将在Lightning页面中了解如何与其他组件进行交互。

使用Lightning Web组件构建Bear-tracking应用程序 – 创建一个子组件并与之交互

创建一个子组件并与之交互

在前面的步骤中,我们的代码库有所增加。现在,花一点时间将我们的清单列表组件重构为几个较小的组件。我们将把熊牌的代码移到一个新的组件中。

创建Bear Tile组件

  1. 在VS Code中,右键单击该lwc文件夹,然后单击SFDX:Create Lightning Web Component
  2. 命名组件bearTile
  3. 打开bearList.html并剪切<!-- Start bear tile -->和之间的所有代码<!-- End bear tile -->
  4. 将代码粘贴到的template标签中bearTile.html。完成后,bearTile.html应如下所示。
    <template>
    	<lightning-card title={bear.Name} class="bear-tile">
    		<div class="slds-var-p-horizontal_small bear-tile-body">
    			<div class="slds-media">
    				<div class="slds-media__figure">
    					<img src={appResources.bearSilhouette} alt="Bear profile" class="bear-silhouette"/>
    				</div>
    				<div class="slds-media__body">
    					<p class="slds-var-m-bottom_xx-small">{bear.Sex__c}</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Age__c} years old</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Height__c} cm</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Weight__c} Kg</p>
    				</div>
    			</div>
    		</div>
    	</lightning-card>
    </template>
  5. 将以下内容替换为bearTile.js
    import { LightningElement, api } from 'lwc';
    import ursusResources from '@salesforce/resourceUrl/ursus_park';
    export default class BearTile extends LightningElement {
    	@api bear;
    	appResources = {
    		bearSilhouette: `${ursusResources}/img/standing-bear-silhouette.png`,
    	};
    }

    我们添加了一个bear装饰有的属性@api。这会将bear属性公开给任何父组件。

  6. 删除bearList.css
  7. bearTile.cssbearTile目录中创建一个新文件,并将以下代码粘贴到该文件中。
    .bear-tile {
      border: 1px solid #d2955d;
      background-color: #fae8d2;
      border-radius: .25rem;
      display: block;
    }
    .bear-silhouette {
      height: 100px;
    }
    .bear-tile-body {
      background: linear-gradient(180deg, rgba(255,255,255,1) 80%, #fae8d2 100%);
    }
  8. 打开bearList.html并更换<!-- Start bear tile --><!-- End bear tile -->与评论<c-bear-tile bear={bear}></c-bear-tile>。一旦完成,bearList.html 应该看起来像这样。
    <template>
    	<lightning-card title="Bears" icon-name="utility:animal_and_nature">
    		<div class="slds-card__body_inner">
    			<!-- Start bear list -->
    			<template if:true={bears.data}>
    				<lightning-input type="search"
    					onchange={handleSearchTermChange}
    					variant="label-hidden"
    					class="slds-var-m-bottom_small"
    					label="Search"
    					placeholder="Search for bears"
    					value={searchTerm}>
    				</lightning-input>
    				<lightning-layout multiple-rows="true" pull-to-boundary="small">
    					<template for:each={bears.data} for:item="bear">
    						<lightning-layout-item key={bear.Id} size="3" class="slds-var-p-around_x-small">
    							<c-bear-tile bear={bear}></c-bear-tile>
    						</lightning-layout-item>
    					</template>
    				</lightning-layout>
    				<!-- No bears found -->
    				<template if:false={hasResults}>
    					<div class="slds-align_absolute-center slds-var-m-vertical_small">
    						This is beary disturbing, we did not find results...
    					</div>
    				</template>
    			</template>
    			<!-- End bear list -->
    			<!-- Data failed to load -->
    			<template if:true={bears.error}>
    				<div class="slds-text-color_error">
    					An error occurred while loading the bear list
    				</div>
    			</template>
    		</div>
    	</lightning-card>
    </template>

    bear将使用我们在前面的步骤中定义的属性引用我们的Bear Tile组件。请注意,我们的组件文件夹和文件已命名bearTile,但我们添加的标签是c-bear-tile。开头c代表默认名称空间,在名称空间后附加小写字母,并用破折号分隔以前的大写字母。

  9. 将更新的代码部署到组织中并测试您的新列表组件。细微的渐变看起来应该更好。

Ursus Park主页上具有自定义样式的熊列表

与Bear List组件进行交互

游骑兵要求能够快速查看熊记录并对其进行编辑,而不必离开主页。让我们单击熊形图块,然后打开一个可编辑的熊形记录表格。

  1. 编辑bearTile.html以下代码并将其添加到<lightning-card title={bear.Name} class="bear-tile">标签之后。
    <div slot="actions">
    	<lightning-button-icon
    		icon-name="utility:search"
    		icon-class="bear-tile-button"
    		variant="bare"
    		alternative-text="Open record"
    		onclick={handleOpenRecordClick}>
    	</lightning-button-icon>
    </div>

    我们添加了一个触发该handleOpenRecordClick功能的编辑按钮。使用actions插槽将按钮放置在闪电卡上。插槽是父组件传递到组件主体的标记的占位符。

  2. bearTile.js在最后一个括号之前编辑并添加以下功能。
    handleOpenRecordClick() {
    	const selectEvent = new CustomEvent('bearview', {
    		detail: this.bear.Id
    	});
    	this.dispatchEvent(selectEvent);
    }

    代码重点:

    • handleOpenRecordClick当用户单击熊图块的打开记录按钮时,将调用该函数。
    • 该函数创建并触发一个bearview包含熊记录ID的自定义事件。
  3. 编辑属性bearList.html并将其添加onbearview={handleBearView}c-bear-tile标签。这使我们能够捕获bearview由tile组件触发的事件。该事件在handleBearView函数中处理。
    <c-bear-tile bear={bear} onbearview={handleBearView}></c-bear-tile>
  4. 将以下内容替换为bearList.js
    import { NavigationMixin } from 'lightning/navigation';
    import { LightningElement, wire } from 'lwc';
    /** BearController.searchBears(searchTerm) Apex method */
    import searchBears from '@salesforce/apex/BearController.searchBears';
    export default class BearList extends NavigationMixin(LightningElement) {
    	searchTerm = '';
    	@wire(searchBears, {searchTerm: '$searchTerm'})
    	bears;
    	handleSearchTermChange(event) {
    		// Debouncing this method: do not update the reactive property as
    		// long as this function is being called within a delay of 300 ms.
    		// This is to avoid a very large number of Apex method calls.
    		window.clearTimeout(this.delayTimeout);
    		const searchTerm = event.target.value;
    		// eslint-disable-next-line @lwc/lwc/no-async-operation
    		this.delayTimeout = setTimeout(() => {
    			this.searchTerm = searchTerm;
    		}, 300);
    	}
    	get hasResults() {
    		return (this.bears.data.length > 0);
    	}
    	handleBearView(event) {
    		// Get bear record id from bearview event
    		const bearId = event.detail;
    		// Navigate to bear record page
    		this[NavigationMixin.Navigate]({
    			type: 'standard__recordPage',
    			attributes: {
    				recordId: bearId,
    				objectApiName: 'Bear__c',
    				actionName: 'view',
    			},
    		});
    	}
    }

    代码重点:

    • 我们导入一个导航mixin,它捆绑了处理导航的实用程序功能。使用mixin,我们可以在不扩展类的情况下向其添加功能。当一个类已经扩展了一个父类(一个类只能扩展一个父类)时,这很有用。
    • 我们的课程将导航混入扩展到了LightningElement基础类。
    • 我们bearviewhandleBearView函数中处理事件。我们从事件详细信息中提取熊记录ID,并使用导航mixin导航到熊记录页面。
  5. 将更新的代码部署到组织中,并测试您是否可以使用图块上的按钮图标导航到熊记录。

这就是步骤。我们已经将组件重构为两个较小的组件:Bear列表和Bear Tile。我们探索了如何使用@api装饰器从父列表组件与子磁贴组件进行通信。我们还看到了如何通过自定义事件从孩子与父母进行交流。

在下一步中,我们将在Lightning页面中了解如何与其他组件进行交互。

使用Lightning Web组件构建Bear-tracking应用程序 – 处理记录清单

创建熊列表组件

公园护林员希望直接从其主页上看到熊的目录。您的任务是实施该清单。

  1. 在VS Code中,右键单击该lwc文件夹,然后单击SFDX:Create Lightning Web Component
  2. 命名组件bearList
  3. 编辑bearList.js-meta.xml文件,并替换<isExposed>false</isExposed>为这些行。
    <isExposed>true</isExposed>
    <targets>
    	<target>lightning__AppPage</target>
    	<target>lightning__RecordPage</target>
    	<target>lightning__HomePage</target>
    </targets>

    这使您的组件可以放置在Lightning App Builder中的任何类型的页面上。

  4. 将以下内容替换为bearList.html
    <template>
    	<lightning-card title="Bears" icon-name="utility:animal_and_nature">
    		<div class="slds-card__body_inner">
    			<!-- Start bear list -->
    			<template if:true={bears}>
    				<lightning-layout multiple-rows="true" pull-to-boundary="small">
    					<template for:each={bears} for:item="bear">
    						<lightning-layout-item key={bear.Id} size="3" class="slds-var-p-around_x-small">
    							<!-- Start bear tile -->
    							<lightning-card title={bear.Name} class="bear-tile">
    								<div class="slds-var-p-horizontal_small bear-tile-body">
    									<div class="slds-media">
    										<div class="slds-media__figure">
    											<img src={appResources.bearSilhouette} alt="Bear profile" class="bear-silhouette"/>
    										</div>
    										<div class="slds-media__body">
    											<p class="slds-var-m-bottom_xx-small">{bear.Sex__c}</p>
    											<p class="slds-var-m-bottom_xx-small">{bear.Age__c} years old</p>
    											<p class="slds-var-m-bottom_xx-small">{bear.Height__c} cm</p>
    											<p class="slds-var-m-bottom_xx-small">{bear.Weight__c} Kg</p>
    										</div>
    									</div>
    								</div>
    							</lightning-card>
    							<!-- End bear tile -->
    						</lightning-layout-item>
    					</template>
    				</lightning-layout>
    			</template>
    			<!-- End bear list -->
    			<!-- Data failed to load -->
    			<template if:true={error}>
    				<div class="slds-text-color_error">
    					An error occurred while loading the bear list
    				</div>
    			</template>
    		</div>
    	</lightning-card>
    </template>

    代码重点:

    • template带有for:eachfor:item指令的标记用于遍历bears记录。每个迭代项都传递给bear属性。
    • 模板的每次迭代均标记有特殊key属性。key在迭代的上下文中必须具有唯一值。那就是我们组件中的熊id。
  5. 将以下内容替换为bearList.js
    import { LightningElement } from 'lwc';
    import ursusResources from '@salesforce/resourceUrl/ursus_park';
    /** BearController.getAllBears() Apex method */
    import getAllBears from '@salesforce/apex/BearController.getAllBears';
    export default class BearList extends LightningElement {
    	bears;
    	error;
    	appResources = {
    		bearSilhouette: `${ursusResources}/img/standing-bear-silhouette.png`,
    	};
    	connectedCallback() {
    		this.loadBears();
    	}
    	loadBears() {
    		getAllBears()
    			.then(result => {
    				this.bears = result;
    			})
    			.catch(error => {
    				this.error = error;
    			});
    	}
    }

    代码重点:

    • 我们导入ursusResources适配器,这使我们能够访问与我们的应用程序关联的静态资源。我们使用此适配器来构建一个appResources对象,该对象在模板中公开熊剪影图像URL。
    • 我们导入getAllBears适配器,这使我们可以与BearController.getAllBears()Apex方法进行交互。该BearController班是您在这个项目开始部署的代码捆绑在一起。该getAllBears方法返回获取所有熊记录的查询结果。
    • 我们实现了该connectedCallback功能,该功能允许我们在组件加载后执行代码。我们使用此函数来调用该loadBears函数。
    • loadBears函数调用getAllBears适配器。适配器调用我们的Apex代码并返回JS promise。我们使用promise将返回的数据保存在bears属性中或报告错误。使用这种方法检索数据称为命令式Apex。
  6. bearList.cssbearList目录中创建一个新文件,并将以下代码粘贴到该文件中。
    .bear-tile {
    		border: 1px solid #d2955d;
    		border-radius: .25rem;
    		display: block;
    }
    .bear-silhouette {
    		height: 100px;
    }

    这些CSS规则为熊卡添加边框,并设置熊剪影图像的高度。

  7. 将更新的代码部署到组织。右键单击默认文件夹,然后单击SFDX:将源部署到组织

将Bear List组件添加到App主页

让我们将新组件添加到应用程序主页。

  1. 在您的组织中,从App Launcher( 应用启动器)中找到并选择Ursus Park。
  2. 单击设置( 安装装置),然后选择编辑页面
  3. 在“自定义组件”下,找到您的bearList组件并将其拖动到页面的左上方。
  4. 单击保存,然后单击返回以返回主页并检查您的工作。

Ursus Park主页上的熊名单

使用有线Apex

现在,我们将探索一种检索熊市名单的新方法。我们将使用有线Apex代替命令式Apex。

  1. 编辑bearList.html并替换<template if:true={bears}><template if:true={bears.data}>
  2. 替换<template for:each={bears} for:item="bear"><template for:each={bears.data} for:item="bear">
  3. 替换<template if:true={error}><template if:true={bears.error}>。在这一点上,除了命令性Apex之外,模板几乎是相同的。现在,我们通过调用bears.data 而不是just来访问空头列表bears,并且现在使用bears.error而不是just来检索错误error
  4. 将以下内容替换为bearList.js
    import { LightningElement, wire } from 'lwc';
    import ursusResources from '@salesforce/resourceUrl/ursus_park';
    /** BearController.getAllBears() Apex method */
    import getAllBears from '@salesforce/apex/BearController.getAllBears';
    export default class BearList extends LightningElement {
    	@wire(getAllBears) bears;
    	appResources = {
    		bearSilhouette: `${ursusResources}/img/standing-bear-silhouette.png`,
    	};
    }

    通过bears使用有线Apex装饰属性,我们大大简化了JS代码。现在,我们需要的所有数据都通过以下一行:@wire(getAllBears) bears;

  5. 将更新的代码部署到组织中,并观察其行为与命令式Apex相同。

在您的Apex呼叫中传递参数

乌尔苏斯公园(Ursus Park)的居民人数正在上升。游骑兵希望能够过滤熊名单以快速找到它们。让我们在熊列表中添加一个搜索栏来帮助他们。

  1. 编辑bearList.html以下代码并将其添加到<template if:true={bears.data}>标签之后。
    <lightning-input type="search"
    	onchange={handleSearchTermChange}
    	variant="label-hidden"
    	class="slds-var-m-bottom_small"
    	label="Search"
    	placeholder="Search for bears"
    	value={searchTerm}>
    </lightning-input>

    这将添加一个搜索输入字段。当其值更改时,我们调用该handleSearchTermChange函数。

  2. </lightning-layout>结束标记后添加以下代码。
    <!-- No bears found -->
    <template if:false={hasResults}>
    	<div class="slds-align_absolute-center slds-var-m-vertical_small">
    		This is beary disturbing, we did not find results...
    	</div>
    </template>

    这会添加一条消息,指示未找到结果。仅当hasResults表达式为false时才会显示此消息。

  3. 将以下内容替换为bearList.js
    import { LightningElement, wire } from 'lwc';
    import ursusResources from '@salesforce/resourceUrl/ursus_park';
    /** BearController.searchBears(searchTerm) Apex method */
    import searchBears from '@salesforce/apex/BearController.searchBears';
    export default class BearList extends LightningElement {
    	searchTerm = '';
    	@wire(searchBears, {searchTerm: '$searchTerm'})
    	bears;
    	appResources = {
    		bearSilhouette: `${ursusResources}/img/standing-bear-silhouette.png`,
    	};
    	handleSearchTermChange(event) {
    		// Debouncing this method: do not update the reactive property as
    		// long as this function is being called within a delay of 300 ms.
    		// This is to avoid a very large number of Apex method calls.
    		window.clearTimeout(this.delayTimeout);
    		const searchTerm = event.target.value;
    		// eslint-disable-next-line @lwc/lwc/no-async-operation
    		this.delayTimeout = setTimeout(() => {
    			this.searchTerm = searchTerm;
    		}, 300);
    	}
    	get hasResults() {
    		return (this.bears.data.length > 0);
    	}
    }

    代码重点:

    • 我们添加了searchTerm反应性属性,并将其作为有线Apex调用的参数传递给searchBears
    • handleSearchTermChange功能用于对搜索输入字段的值的变化做出反应。更新searchTerm反应性时,我们有目的地引入了300毫秒的延迟。如果有更新待处理,我们将取消它,并在300毫秒内重新安排一个新的更新。当用户键入字母以形成单词时,此延迟会减少Apex呼叫的次数。每个新字母都会触发对的呼叫,handleSearchTermChange但理想情况下,searchBears 只有在用户完成输入后才被调用一次。这种技术称为反跳。
    • 我们公开该hasResults表达式以检查搜索是否返回了熊。
  4. 将更新后的代码部署到组织中,并检查搜索是否成功,无论结果如何。

Ursus Park主页上的已过滤熊列表

这就是步骤。我们已经了解了如何使用命令式Apex然后使用有线Apex处理记录列表,并且学习了如何在Apex调用中传递参数。在此过程中,我们组件的代码已显着增长,因此现在让我们将其分为子组件以使其易于维护。

使用Lightning Web组件构建Bear-tracking应用程序 – 处理单个记录

你会做什么

熊熊游乐园管理员需要您的帮助来追踪在公园里游荡的熊。他们已经在Salesforce中输入了一些信息,但是他们需要您为他们提供定制的应用程序体验。

创建Bear位置组件

  1. 在VS Code中,右键单击该lwc文件夹,然后单击SFDX:Create Lightning Web Component
  2. 命名组件bearLocation
  3. 编辑bearLocation.js-meta.xml文件,并替换<isExposed>false</isExposed>为这些行。
    <isExposed>true</isExposed>
    <targets>
    	<target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
    	<targetConfig targets="lightning__RecordPage">
    		<objects>
    			<object>Bear__c</object>
    		</objects>
    	</targetConfig>
    </targetConfigs>

    这样可以确保您的组件只能放置在Bear记录页面上。

  4. 将内容替换为bearLocation.html以下标记。
    <template>
    	<lightning-card title={cardTitle} icon-name="standard:address">
    		<lightning-map map-markers={mapMarkers} zoom-level="12"></lightning-map>
    	</lightning-card>
    </template>

    代码重点:

    • 我们根据cardTitle表达式显示带有动态标题的卡片组件。
    • 该卡包含一个地图组件,其标记由定义mapMarkers
  5. 用以下内容替换的内容bearLocation.js
    import { LightningElement, api, wire } from 'lwc';
    import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
    // Set Bear object fields
    const NAME_FIELD = 'Bear__c.Name';
    const LOCATION_LATITUDE_FIELD = 'Bear__c.Location__Latitude__s';
    const LOCATION_LONGITUDE_FIELD = 'Bear__c.Location__Longitude__s';
    const bearFields = [
    	NAME_FIELD,
    	LOCATION_LATITUDE_FIELD,
    	LOCATION_LONGITUDE_FIELD
    ];
    export default class BearLocation extends LightningElement {
      @api recordId;
      name;
      mapMarkers = [];
      @wire(getRecord, { recordId: '$recordId', fields: bearFields })
      loadBear({ error, data }) {
        if (error) {
          // TODO: handle error
        } else if (data) {
          // Get Bear data
          this.name =  getFieldValue(data, NAME_FIELD);
          const Latitude = getFieldValue(data, LOCATION_LATITUDE_FIELD);
          const Longitude = getFieldValue(data, LOCATION_LONGITUDE_FIELD);
          // Transform bear data into map markers
          this.mapMarkers = [{
            location: { Latitude, Longitude },
            title: this.name,
            description: `Coords: ${Latitude}, ${Longitude}`
          }];
        }
      }
      get cardTitle() {
        return (this.name) ? `${this.name}'s location` : 'Bear location';
      }
    }

    代码重点:

    • 我们导入了一个getRecord适配器,该适配器使我们能够使用Lightning Data Service检索记录而无需编写Apex。
    • 我们导入一个getFieldValue辅助函数来检索字段值。
    • 我们Bear__cbearFields常量中汇编来自对象的硬编码字段名称的列表。请注意,这种方法不支持参照完整性。在编译时无法检查对象和字段的存在。这意味着Bear__c即使在您的代码中使用了它,也可以删除它的任何字段。我们在下一个组件中使用另一种支持引用完整性的方法。
    • recordId装饰为的属性会@api自动接收当前记录ID。
    • 我们@wireloadBear函数上使用装饰器来获取数据和错误,然后将它们传递给函数。@wire配置为getRecord使用某些参数调用适配器功能。这些参数是记录ID和我们希望检索的记录字段列表。感谢@wire装饰器,loadBear当组件加载或记录id更改时,它会自动调用。
    • 在此组件的第一个版本中,我们不处理错误。我们暂时跳过。
    • 如果没有错误,我们将保存熊的名称并使用熊的坐标构建地图标记。
  6. 将更新的代码部署到组织。右键单击默认文件夹,然后单击SFDX:将源部署到组织

将Bear位置组件添加到Bear Record页面

现在我们已经实现了组件,让我们将其添加到页面中以对其进行查看。

  1. 在您的组织中,导航至Bears标签并打开任何记录。
  2. 单击设置( 安装装置),然后选择编辑页面
  3. 在“定制组件”下,找到您的bearLocation组件并将其拖到右侧列的顶部。
  4. 点击保存
  5. 由于这是我们第一次修改标准Bear记录页面,因此我们需要激活更新的页面,以便我们的用户可以看到我们所做的事情。点击激活
  6. 单击应用程序默认选项卡。
  7. 点击分配为应用默认值
  8. 检查Ursus公园
  9. 单击下一步,下一步,然后单击保存
  10. 单击上一步返回到Bear记录页面并检查您的工作。

熊记录页面上的熊位置组件

做得好!现在,我们可以在地图上看到熊。让我们继续自定义熊记录页面。

创建Bear Supervisor组件

公园护林员被分配来监督特定的熊。如果发现熊做了鲁doing的事情,公园员工必须能够迅速联系到熊的主管。您将在熊记录页面上添加熊主管卡来提供帮助。

  1. 在VS Code中,右键单击该lwc文件夹,然后单击SFDX:Create Lightning Web Component
  2. 命名组件bearSupervisor
  3. 编辑bearSupervisor.js-meta.xml文件,并替换<isExposed>false</isExposed>为这些行。
    <isExposed>true</isExposed>
    <targets>
    	<target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
    	<targetConfig targets="lightning__RecordPage">
    		<objects>
    			<object>Bear__c</object>
    		</objects>
    	</targetConfig>
    </targetConfigs>

    这使您的组件可以放置在Bear记录页面上。

  4. 将以下内容替换为bearSupervisor.html
    <template>
    	<lightning-card title="Supervisor" icon-name="standard:people">
    		<div class="slds-var-m-around_medium">
    			<!-- Show supervisor when bear is loaded -->
    			<template if:true={bear.data}>
    				<lightning-record-form
    					object-api-name="Contact"
    					record-id={supervisorId}
    					layout-type="Compact">
    				</lightning-record-form>
    			</template>
    			<!-- Data failed to load -->
    			<template if:true={bear.error}>
    				<div class="slds-text-color_error">
    					An error occurred while loading the bear record
    				</div>
    			</template>
    		</div>
    	</lightning-card>
    </template>

    代码重点:

    • if:true加载熊数据后,我们使用指令有条件地呈现主管。
    • 我们使用来显示主管(联系人)记录的紧凑视图lightning-record-form
    • 如果无法加载Bear记录if:true,则使用指令和error属性有条件地呈现错误消息。
  5. 将以下内容替换为bearSupervisor.js
    import { LightningElement, api, wire } from 'lwc';
    import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
    // Import Bear object fields
    import SUPERVISOR_FIELD from '@salesforce/schema/Bear__c.Supervisor__c';
    const bearFields = [SUPERVISOR_FIELD];
    export default class BearSupervisor extends LightningElement {
    	@api recordId; // Bear Id
    	@wire(getRecord, { recordId: '$recordId', fields: bearFields })
      bear;
    	get supervisorId() {
    		return getFieldValue(this.bear.data, SUPERVISOR_FIELD);
    	}
    }

    代码重点:

    • 我们Bear__c.Supervisor__c通过模式导入来导入字段,而不是像以前在熊位置组件中那样使用硬编码字符串。这种方法的主要好处是可以确保引用完整性。
    • 我们使用@wire装饰器和getRecord适配器检索熊记录。
    • 我们公开一个supervisorId表达式。该表达式使用该getFieldValue函数来检索主管字段的值。
  6. 将更新的代码部署到组织。右键单击默认文件夹,然后单击SFDX:将源部署到组织

将Bear Supervisor组件添加到Bear Record页面

让我们将新组件添加到熊记录页面。

  1. 在您的组织中,通过单击“熊”选项卡并单击任何熊来导航到熊记录页面。在熊记录页面中,单击设置( 安装装置),然后选择编辑页面
  2. 在“定制组件”下,找到您的bearSupervisor组件并将其拖动到bearLocation组件下。
  3. 单击保存返回以返回到记录页面并检查您的工作。

熊记录页面上的熊主管组件

这就是步骤。我们已经看到了Lightning Web组件如何使用@wire适配器处理单个记录。现在让我们进入记录列表。