使用Lightning Web Components开放源代码访问Salesforce数据 创建Salesforce环境

学习目标

在此项目中,您将:

  • 设置您的Salesforce环境。
  • 在Salesforce中创建具有不同字段类型和关系的数据模型。
  • 从使用Lightning Web Components Open Source构建的会议管理应用程序中验证和获取Salesforce数据。

在你开始之前

在执行此动手项目中的步骤之前,请确保已完成使用Lightning Web Components Open Source构建您的第一个应用程序项目 。您在此处所做的工作基于该项目中的概念和所做的工作。 

准备开始这个项目了吗?如果您已经创建了Trailhead Playground,请立即滚动到该页面底部并单击Launch来打开它,然后按照“获取用户名和密码”下面的步骤进行操作,然后单击“验证” 完成此步骤。 

如果尚未创建Trailhead Playground,请继续并按照此步骤中的说明进行操作。

创建您的Trailhead游乐场

要创建新的Trailhead Playground,请滚动至该页面的底部,单击Launch旁边的向下箭头,然后选择Create a Trailhead Playground。创建Trailhead游乐场后,单击“启动” 以打开游乐场。

注意

要了解有关Trailhead游乐场的更多信息,请获取 Trailhead游乐场管理徽章。 

获取您的用户名和密码

大多数时候,您不需要知道Trailhead Playground的用户名和密码。但是,对于此项目,您需要了解它们,因为您将从外部应用程序登录到Salesforce,该外部应用程序是使用Lightning Web Components Open Source在上一个项目中构建的会议管理应用程序。

如果您在组织中看到一个标签为“获取登录凭据”的标签,那就太好了!请按照以下步骤操作。 

如果没有,请单击 应用启动器  以启动App Launcher,然后单击Playground Starter并按照步骤进行操作。如果您没有看到Playground Starter应用程序,请在Trailhead帮助中签出 查找Trailhead Playground的用户名和密码

  1. 单击获取您的登录凭据选项卡,并记下您的用户名。 

您在Trailhead Tips应用程序中的用户名。

  1. 单击重置我的密码。这会将电子邮件发送到与您的用户名关联的地址。
  2. 单击电子邮件中的链接。
  3. 输入新密码,确认,然后单击更改密码

获取您的安全令牌

每当您尝试从公司的受信任IP范围之外的IP地址访问Salesforce API时,都需要一个安全令牌。这是生成一个的方法。

  1. 在您的Trailhead游乐场中,单击您的个人资料图片,然后从菜单中单击“设置”
    屏幕显示设置选项。
  2. 从可用选项列表中,单击“重置我的安全令牌”,然后在显示的页面上单击“重置安全令牌”按钮。
    屏幕上显示“重置安全令牌”页面,突出显示了“重置安全令牌”按钮。
  3. 您会收到一封包含安全令牌的电子邮件。记下此令牌。

您已经成功创建并设置了一个新的Salesforce环境,并收到了用于访问Salesforce API的安全令牌。接下来,在Salesforce中创建数据模型以存储会议管理应用程序所需的会话和发言人详细信息。

将Lightning Web Components开源转换为Salesforce – 使用Apex检索数据

使用Apex检索数据

您在上一个项目中构建的Node.js应用程序运行SOQL查询,以从Salesforce平台检索会话列表。为了在Salesforce上检索该数据,您需要将Node.js后端逻辑转换为Apex代码。Apex是一种强类型的,面向对象的编程语言,它使开发人员可以结合对API的调用在Salesforce服务器上执行流和事务控制语句。

注意

Apex仅在特定的用例中才需要,例如获取记录及其相关记录。与单个记录数据进行交互时,可以使用User Interface API的功能。这使您可以使用预构建的线适配器和函数仅通过JavaScript即可对记录执行CRUD操作,而无需编写任何Apex行。

在此步骤中,您将编写一个Apex控制器,该控制器执行SOQL查询并将其公开为可以由您的组件调用的端点。

创建一个Apex控制器

    1. 在VS Code中,右键单击该classes文件夹,然后单击SFDX:Create Apex Class
    2. 输入名称SessionController
    3. 如果VS Code询问,请选择force-app/main/default/classes作为要添加SessionController.cls到的目录。
    4. 在新打开的文件中,将默认代码替换为以下代码。
public with sharing class SessionController {
  @AuraEnabled(cacheable=true)
  public static List<Session__c> getSessions(String searchKey) {
    if (String.isBlank(searchKey)) {
      return [SELECT Id, Name, toLabel(Room__c), Description__c, format(Date_and_Time__c) dateTime,
      (SELECT Speaker__r.Id, Speaker__r.Name, Speaker__r.Description, Speaker__r.Email, Speaker__r.Picture_URL__c FROM Session_Speakers__r)
      FROM Session__c ORDER BY Date_and_Time__c LIMIT 100];
    } else {
      String key = '%' + searchKey + '%';
      return [SELECT Id, Name, toLabel(Room__c), Description__c, format(Date_and_Time__c) dateTime,
      (SELECT Speaker__r.Id, Speaker__r.Name, Speaker__r.Description, Speaker__r.Email, Speaker__r.Picture_URL__c FROM Session_Speakers__r)
      FROM Session__c WHERE Name LIKE :key ORDER BY Date_and_Time__c LIMIT 100];
    }
  }
  @AuraEnabled(cacheable=true)
  public static Session__c getSession(Id sessionId) {
    List<Session__c> sessions = [SELECT Id, Name, toLabel(Room__c), Description__c, format(Date_and_Time__c) dateTime,
      (SELECT Speaker__r.Id, Speaker__r.Name, Speaker__r.Description, Speaker__r.Email, Speaker__r.Picture_URL__c FROM Session_Speakers__r)
      FROM Session__c WHERE Id = :sessionId];
    if (sessions.size() != 1) {
      throw new AuraHandledException('Could not find session');
    }
    return sessions[0];
  }
}

@AuraEnabled(cacheable=true)声明将方法公开为端点,以便您的组件可以调用它们。它还支持对方法返回的数据进行客户端缓存。您在此处编写的代码比其Node.js等效代码短,因为您不必担心身份验证或异步运行查询。

  1. 保存SessionController.cls

使用电线检索数据

现在我们有了端点,让我们替换模拟数据实现,并使用Wire Service用真实数据检索会话记录。此服务是Salesforce平台上的特殊实现,它使用声明性方法提供了优化的读取操作和客户端缓存。让我们看看如何构建它。

    1. 打开sessionList.js
    2. 用以下代码替换前两行中的导入代码。
import { LightningElement, wire } from 'lwc';
import getSessions from '@salesforce/apex/SessionController.getSessions';

这将导入从您的Apex方法自动生成的电线适配器。 

    1. 在下面添加以下代码 sessions = [];
searchKey = '';
@wire(getSessions, { searchKey: '$searchKey' })
wiredSessions({ error, data }) {
  if (data) {
    this.sessions = data;
  } else if (error) {
    this.sessions = [];
    throw new Error('Failed to retrieve sessions');
  }
}

电线使用getSessions映射到我们的Apex端点的适配器。使用searchKey映射到searchKey属性的参数调用导线。请注意,参数值以带有$前缀的字符串形式传递。这意味着此参数是反应性的:每次searchKey更改时都会调用电线。

    1. 删除connectedCallback功能。
    2. handleSearchKeyInput以下代码替换该函数。
handleSearchKeyInput(event) {
  clearTimeout(this.delayTimeout);
  const searchKey = event.target.value;
  // eslint-disable-next-line @lwc/lwc/no-async-operation
  this.delayTimeout = setTimeout(() => {
      this.searchKey = searchKey;
  }, 300);
}

不再在客户端执行过滤。searchKey现在将其传递到线路,以便Apex返回已过滤的会话列表。您正在searchKey通过对更新应用300毫秒的延迟来取消更新属性。这是为了避免大量的Apex方法调用。

    1. 将该handleSessionClick函数替换为:
handleSessionClick(event) {
  const { sessionId } = event.currentTarget.dataset;
  const navigateEvent = new CustomEvent('navigate', {
    detail: {
      state: 'details',
      sessionId: sessionId
    }
  });
  this.dispatchEvent(navigateEvent);
}

现在,您可以使用会话记录ID而不是会话列表索引来导航到会话详细信息页面。

    1. 保存sessionList.js
    2. 打开sessionList.html
    3. 用以下代码替换文件内容。
<template>
  <div class="list">
    <input type="search" placeholder="Search sessions..."
     oninput={handleSearchKeyInput} />
    <template for:each={sessions} for:item="session">
      <a key={session.Id} class="session" data-session-id={session.Id} onclick={handleSessionClick}>
         <div>
           <p class="title">{session.Name}</p>
           <p class="icon time">{session.dateTime}</p>
           <p class="icon room">{session.Room__c}</p>
         </div>
         <template if:true={session.Session_Speakers__r}>
           <div class="speaker-pictures">
             <template for:each={session.Session_Speakers__r} for:item="speaker">
               <img key={speaker.Speaker__r.Id} src={speaker.Speaker__r.Picture_URL__c}
                  alt={speaker.Speaker__r.Name} title={speaker.Speaker__r.Name}>
              </template>
           </div>
       </template>
     </a>
    </template>
  </div>
</template>

模板结构基本保持不变,但是现在您使用Salesforce记录字段名称。就像您之前在Node.js后端中所做的那样,这省去了用JavaScript映射字段名称的工作。在真实的项目中,您将直接在组件模板中使用Salesforce字段名称。

    1. 保存 sessionList.html.
    2. 打开 sessionDetails.js.
    3. 将文件内容替换为:
import { LightningElement, api, wire } from 'lwc';
import getSession from '@salesforce/apex/SessionController.getSession';
export default class SessionDetails extends LightningElement {
  @api sessionId;
  session;
  @wire(getSession, { sessionId: '$sessionId' })
  wiredSession({ error, data }) {
    if (data) {
      this.session = data;
    } else if (error) {
      this.session = undefined;
      throw new Error('Failed to retrieve session');
    }
  }
  handleSessionsClick() {
    const navigateEvent = new CustomEvent('navigate', {
      detail: {
        state: 'list'
      }
    });
    this.dispatchEvent(navigateEvent);
  }  
}

就像for一样sessionList,您将getSessionApex方法连接到session属性。您将sessionId公共属性作为反应性参数传递给getSession

    1. 保存sessionDetails.js
    2. 打开sessionDetails.html
    3. 将文件内容替换为:
<template>
  <template if:true={session}>
    <h2><a href="#" onclick={handleSessionsClick}>Sessions</a> > {session.Name}</h2>
    <p class="icon time">{session.dateTime}</p>
    <p class="icon room">{session.Room__c}</p>
    <h3>Abstract</h3>
    <div class="abstract">{session.Description__c}</div>
    <h3>Speakers</h3>
    <div class="speaker-list">
      <template if:true={session.Session_Speakers__r}>
        <template for:each={session.Session_Speakers__r} for:item="speaker">
          <c-speaker-card key={speaker.Speaker__r.id} speaker={speaker.Speaker__r}>
          </c-speaker-card>
        </template>
      </template>
    </div>
  </template>
</template>
    1. 保存sessionDetails.html
    2. 打开speakerCard.html
    3. 用以下代码替换文件内容。
<template>
  <div class="card">
    <div class="header">
      <img src={speaker.Picture_URL__c} alt="Speaker picture">
      <div>
        <p class="title">{speaker.Name}</p>
        <p class="icon email">{speaker.Email}</p>
      </div>
    </div>
    {speaker.Description}
  </div>
</template>
  1. 保存speakerCard.html
  2. 通过右键单击force-app文件夹并单击SFDX:将源部署到组织来重新部署组件。

会话列表显示平台数据的完整应用程序。

项目总结

恭喜你!您已成功转换了Lightning Web Component开源应用程序并将其部署在Salesforce平台上。

您刚刚了解了Salesforce平台提供的强大声明功能,从而减少了构建应用程序所需实现的代码量。查看其他许多Lightning Web Component项目和模块,以了解有关使您更快地构建现代应用程序的技术的更多信息。

将Lightning Web Components开源转换为Salesforce – 转换Salesforce平台的组件

转换Salesforce平台的组件

在此步骤中,您将为Node.js应用程序编写的Lightning Web组件转换为Salesforce平台的组件。

注意

除非另有说明,否则此步骤中的所有操作都将应用于/force-app/main/default/lwc创建的Salesforce DX项目中目录下的文件夹。

复制组件文件

  1. 副本appsessionDetailssessionList,和speakerCard组件文件夹从以前项目/src/client/modules/my目录。
  2. 将这四个文件夹粘贴到Salesforce DX项目/force-app/main/default/lwc目录中。
  3. 删除force-app/main/default/lwc/app/__tests__文件夹,因为我们将不在此项目中测试组件。

添加组件元数据

为了显示Lightning Experience中的组件,Salesforce平台需要一些称为元数据的额外数据。 

    1. 打开Visual Studio代码
    2. 文件>打开
    3. 选择您的lightning-conference文件夹,然后单击“打开”
    4. 在文件资源管理器中导航到目录force-app/main/default/lwc
    5. app.js-meta.xmlapp目录中创建一个文件。
    6. 将此内容粘贴到文件中:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>49.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel>Conference App</masterLabel>
  <targets>
    <target>lightning__AppPage</target>
  </targets>
</LightningComponentBundle>

isExposed设置为的标志true公开了要在Lightning App Builder中使用的组件,而该masterLabel属性使您可以为其指定用户友好名称。通过lightning__AppPage目标,您可以将该组件放置在Lightning应用程序页面中,就像您之前创建的一样。

    1. 保存app.js-meta.xml文件。
    2. sessionDetails.js-meta.xmlsessionDetails目录中创建一个文件。
    3. 将此内容粘贴到文件中:
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>49.0</apiVersion>
  <isExposed>false</isExposed>
</LightningComponentBundle>
  1. 保存sessionDetails.js-meta.xml文件。
  2. 复制sessionDetails.js-meta.xmlsessionList 目录中,并将其重命名为sessionList.js-meta.xml
  3. 复制speakerCard 目录中的sessionDetails.js-meta.xml并将其重命名为speakerCard.js-meta.xml

此时,所有组件目录都应包含一个如下.js-meta.xml文件:

 组件文件列表,包括元数据文件。

更新组件命名空间

在上一个项目中,组件放置在my充当名称空间的文件夹中。在Salesforce平台上,您使用默认名称空间- c。实际上,这只是意味着您需要用my-组件标记中的c-前缀替换组件标签的前缀。

  1. 在VS Code中,单击“搜索”图标 搜索图标。
  2. my-在搜索字段中输入。
  3. Enter键,您应该看到“ 2个文件中有6个结果”(app.html和sessionDetails.html)。
  4. c-在替换字段中输入。
  5. 单击全部替换图标,替换所有图标。然后确认替换。

命名空间搜索并在VS Code中进行替换。

使用模拟数据测试转换

为了快速测试组件的转换,让我们用模拟数据替换数据检索。您将在下一步中获取Salesforce数据。

    1. 打开 sessionList.js
    2. 去掉 import { getSessions } from 'data/sessionService';
    3. connectedCallback以下代码替换函数中的三行代码。
this.sessions = this.allSessions = [
  {
    id: '1',
    name: 'Mock session',
    dateTime: '2099-01-01 00:00:00',
    room: 'Mock room',
    description: "Mock description",
    speakers: [
      {
        id: '1',
        name: 'Mock speaker 1',
        bio: 'Bio for mock speaker 1',
        email: 'mock1@trailhead.com',
        pictureUrl:'https://developer.salesforce.com/files/js-dev/speaker-images/john_doe.jpg'
      },
      {
        id: '2',
        name: 'Mock speaker 2',
        bio: 'Bio for mock speaker 2',
        email: 'mock2@trailhead.com',
        pictureUrl:'https://developer.salesforce.com/files/js-dev/speaker-images/laetitia_arevik.jpg'
      }
    ]
  }
];
    1. 保存 sessionList.js
    2. 打开 sessionDetails.js
    3. 去掉 import { getSession } from 'data/sessionService';
    4. 替换this.session = getSession(id);为以下代码。
this.session = {
  id: '1',
  name: 'Mock session',
  dateTime: '2099-01-01 00:00:00',
  room: 'Mock room',
  description: "Mock description",
  speakers: [
    {
      id: '1',
      name: 'Mock speaker 1',
      bio: 'Bio for mock speaker 1',
      email: 'mock1@trailhead.com',
      pictureUrl: 'https://developer.salesforce.com/files/js-dev/speaker-images/john_doe.jpg'
    },
    {
      id: '2',
      name: 'Mock speaker 2',
      bio: 'Bio for mock speaker 2',
      email: 'mock2@trailhead.com',
      pictureUrl: 'https://developer.salesforce.com/files/js-dev/speaker-images/laetitia_arevik.jpg'
    }
  ]
};
  1. 保存 sessionDetails.js

将应用程序组件添加到闪电页面

此时,您的组件已准备好部署到Salesforce平台,并且可以将它们添加到您先前设置的Lightning Page中。

    1. 在VS Code中,右键单击该force-app文件夹,然后单击SFDX:将源部署到组织

您应该在VS Code的输出选项卡中看到以下文本。

  1. 在Windows上按Ctrl + Shift + P或在macOS上按Cmd + Shift + P来打开命令面板。
  2. 类型 SFDX
  3. 选择SFDX:打开Default Org。这将在浏览器中打开您的Salesforce组织。
  4. 导航到会议应用程序的“议程”选项卡。
  5. 单击设置图标,安装装置 然后选择编辑页面
  6. 在左侧导航列表中,向下滚动到“自定义”部分,找到您的Conference App组件并将其拖动到显示为的组件占位符上:在此处添加组件。
  7. 点击保存
  8. 单击返回以返回到应用程序。

单击会话条目,并确保您可以导航到列出的单个会话。

具有模拟数据的议程页面。

我们在Lightning应用程序中不需要标题,因此让我们调整应用程序的样式和结构。

调整组件的样式和结构

    1. 打开 app.html
    2. 删除header标签及其内容。
    3. <main class="content">用此代码替换开始标签。
<lightning-card>
  <div class="slds-var-p-horizontal_small">
    1. 将结束</main>标记替换为:
  </div>
</lightning-card>
  1. 保存 app.html
  2. 右键单击app.css资源管理器中的文件,选择“ SFDX:从项目和组织中删除”,然后单击“删除源”
  3. 编辑sessionList.css,删除:host规则并保存文件。
  4. 编辑sessionDetails.css,删除:host规则并保存文件。
  5. 通过右键单击force-app文件夹并单击SFDX:将源部署到组织来重新部署组件。

做得好,您的应用现在看起来更好(您可能需要刷新页面几次以清除缓存)。

具有固定样式和模拟数据的应用程序。

在下一步中,将模拟数据替换为真实的Salesforce数据。

将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页面中了解如何与其他组件进行交互。