将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开发环境。在下一步中,您将创建一个新项目并开始构建该应用程序。