适用于Visualforce开发人员的Lightning Web组件

适用于Visualforce开发人员的Lightning Web组件 – 使用Salesforce数据

学习目标

完成本单元后,您将能够:

  • 意识到根据特定用例选择最佳方式使用Salesforce数据的重要性。
  • 描述闪电数据服务如何与Visualforce中的标准控制器进行比较。
  • 说明在Lightning Web组件中使用Apex与在Visualforce中使用Apex有何不同。

Visualforce与Lightning Web组件中的数据访问

作为Visualforce开发人员,您熟悉在页面中使用标准控制器和绑定Apex控制器方法以使用Salesforce数据的情况。在Lightning Web Components中,您的JavaScript代码与Lightning Data Service(LDS)或Apex代码进行交互。

传统的Visualforce数据访问 闪电Web组件数据访问
客户端如何在Visualforce中访问服务器上的数据 客户端如何在Lightning Web Components中访问服务器上的数据

检索或修改数据的Visualforce页面使用标准控制器或Apex控制器。传统上,客户端在页面加载或作为操作时调用控制器方法。方法运行后,Visualforce引擎将生成最终标记并将其发送给客户端。

检索或修改数据的Lightning Web组件使用Lightning Data Service或Apex方法。客户端使用JavaScript调用Lightning Data Service或Apex方法。在运行Lightning Data Service或Apex方法之后,Lightning Web Components引擎会将所需的最少数据返回给客户端。客户端上的JavaScript处理数据并生成最终标记。

闪电数据服务与StandardController

Lightning Data Service 是在Lightning Web组件中使用Salesforce数据的首选(也是最简单)方式。闪电数据服务是与Visualforce标准控制器类似的概念。在JavaScript中使用Lightning Data Service在不编写Apex代码的情况下读取,创建或修改单个记录,或读取某些元数据。Lightning Data Service提供了高级功能,例如组件之间的缓存和同步。

注意

要使用Lightning Data Service,您有两个选择:使用允许您构建表单的基本组件,或使用LDS电线适配器或功能。使用Lightning Data Service的代码非常具体,并且在Lightning Web组件和Salesforce数据 模块中的“使用Lightning Data Service来处理数据”中进行了详细说明 。

Visualforce中的Apex与Lightning Web Components中的Apex

Lightning Data Service不能满足所有用例的要求。例如,当您要自定义单记录数据事务或对单个事务执行多记录操作时,需要Apex。在将Apex与Lightning Web组件一起使用之前,请注意在Lightning Web组件中使用Apex与在Visualforce中使用Apex是不同的。主要区别在于:

  • 方法是无状态的。
  • 方法必须是@AuraEnabled,并且可以标记为可缓存。
  • 您导入Apex方法,然后调用它们。
  • 您绑定组件以在元数据xml文件中记录页面,并在JavaScript文件中访问记录ID。
  • 正确的错误处理涉及引发异常,而不是使用页面消息。

让我们进一步探讨这些差异。

查看状态与无状态方法

Visualforce使用视图状态来维护服务器请求之间的状态。视图状态将重新创建页面,并将状态传递到向导和指导工作流程中的不同页面。在Lightning Web组件中,服务器请求是无状态的。这对您编写Apex调用的方式具有重要意义。每次进行Apex调用时,都必须传递该方法所需的所有信息,并且该方法必须返回组件所需的所有信息。此外,要从Lightning Web组件调用Apex方法,该方法必须带有注释@AuraEnabled

让我们研究一下Visualforce Apex控制器。

AccountListControllerVisualforce.cls

public with sharing class AccountListControllerVisualforce {
    public List<Account> accounts { get; private set; }
    public Integer numberOfEmployees { get; set; }
    public void queryAccounts() {
        // In real world, probably more complex logic here
        this.accounts = [
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees = :numberOfEmployees
        ];
    }
}

代码重点:

  • 第2至3行:accounts和 numberOfEmployees属性定义为实例变量,它们是控制器视图状态的一部分。
  • 第6至9行:该queryAccounts方法numberOfEmployees在 accounts变量中存储了由过滤的帐户列表,我们可以在Visualforce页面中引用该列表。

以下是将该AccountListController for Visualforce转换为Lightning Web组件的控制器的方法。

  1. 使用@AuraEnabled,使用cacheable属性或不使用属性注释Apex方法。(默认情况下,数据 不可在客户端中缓存。)
  2. 通过使其成为无状态static且独立于所有实例变量和属性的方法,确保它们是无状态的。
  3. 将方法需要的所有内容作为参数传递。
  4. 确保每种方法都返回组件所需的一切。

这是适用于Lightning Web组件的控制器。

AccountListControllerLwc.cls

public with sharing class AccountListControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Account> queryAccounts(Integer numberOfEmployees) {
        return [ // Return whatever the component needs
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees >= :numberOfEmployees
        ];
    }
}

代码重点:

  • 第2行:使用注释queryAccounts方法 @AuraEnabled,并将其cacheable属性设置为true。
  • 第3行:创建queryAccounts方法static,并将其定义numberOfEmployees为Integer参数。
  • 第4-8行:该queryAccounts方法返回过滤后的帐户列表。

注意

将方法标记为可缓存时,避免重复调用服务器。但是,在刷新缓存之前,可能不会返回新添加或更改的记录版本。要了解缓存Apex方法的含义以及如何刷新缓存,请参阅Lightning Web Components和Salesforce数据 模块中的“使用Apex处理数据” 。

在Visualforce vs Lightning Web组件中调用Apex

在Visualforce中,要在组件标记中引用Apex方法,可以通过将Apex控制器指定为<apex:page>标签中的属性来将其绑定到Visualforce页面。在Lightning Web Components中,我们没有绑定控制器并引用页面中的Apex方法,而是将这些方法导入JavaScript文件,然后在JavaScript中调用这些方法。

import queryAccounts from '@salesforce/apex/AccountListControllerLwc.queryAccounts;

与Lightning Web组件中的Apex方法进行交互的方式有两种:连接方法或强制调用方法。接线方法将控件委派给Lightning Web Components引擎并创建响应服务。强制调用Apex会导致一次性调用。确切地说,何时以及如何使用每个选项超出了本模块的范围。要了解更多信息,请参阅 Lightning Web Components和Salesforce数据 模块。

在Visualforce vs Lightning Web组件中访问记录ID

在Visualforce中,访问Apex控制器中的记录ID非常简单。使用标准控制器,您可以IdApexPages.StandardController对象中检索记录 。

例如,考虑使用此Apex控制器,该控制器通过扩展使用“客户”标准控制器的页面来显示与客户相关的联系人。

AccountControllerVisualforce.cls

public with sharing class AccountControllerVisualforce {
    public List<Contact> contacts { get; private set; }
    private ApexPages.StandardController standardController;
    public AccountController(ApexPages.StandardController standardController) {
        this.standardController = standardController;
        this.contacts = new List<Contact>();
    }
    public void queryRelatedContacts() {
        this.contacts = [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE AccountId = :standardController.getId() // (2)
        ];
   }
}

代码重点:

  • 第4行:standardController因为页面使用Account标准控制器,所以我们在构造函数中收到一个对象。
  • 第12行:要获取Id页面引用的Account记录,我们getIdstandardController对象上调用方法 。这样,我们可以查询联系人以获取相关的客户记录,并为其过滤Id

在Lightning Web组件中,访问Apex中的记录ID不太简单。要访问记录ID:

  1. 公开组件,使其在记录页面上可用。
  2. 在JavaScript中,声明recordId为公共属性。父组件(记录Flexipage)填充recordId属性的值 。
  3. recordId在Apex方法调用中将as作为参数传递。

让我们来看一个例子。

accountDetails.js-meta.xml

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

accountDetails.js

import { LightningElement, wire } from 'lwc';
import queryRelatedContacts from '@salesforce/apex/AccountControllerLwc.queryRelatedContacts';
export default class AccountInfo extends LightningElement {
    @api recordId;
    @wire(queryRelatedContacts, { accountId: '$recordId' })
    contacts;
}

AccountControllerLwc.cls

public with sharing class AccountControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Contact> queryRelatedContacts(Id accountId) {
        return [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE AccountId = :accountId
        ];
    }
}

代码重点:

accountDetails.js-meta.xml

  • 第4-7行:我们将其设置isExposed为true并添加 lightning__RecordPage为该组件的目标,以使该组件在记录页面上可用。

accountDetails.js

  • 第4行:我们声明该recordId属性,并使用修饰它以使其公开@api。Flexipage会填充 recordId属性。
  • 第5-6行:我们将recordId属性作为参数传递给 queryRelatedContactsApex方法的 accountId参数。(在这种情况下,我们使用了 @wire,但是我们可以强制性地调用Apex。)结果存储在contacts属性中。

AccountControllerLwc.cls

  • 第3行:queryRelatedContactsApex方法接收 accountId作为参数。请记住,该方法是无状态的。
  • 第4-8行:该queryRelatedContacts方法用于 accountId返回客户的联系人。

Visualforce与Lightning Web组件中的服务器错误

在Visualforce中,您使用诸如<apex:pageMessages>和之类的 标记 <apex:pageMessage>以在Visualforce页面上以不同方式显示错误。为了使这些标记正常工作,必须在Apex控制器中处理异常并将消息添加 到页面,如下所示:

try {
    // Perform logic that may throw an exception.
} catch (Exception e) {
    ApexPages.addMessages(e);
}

在Lightning Web组件中,我们处理JavaScript文件中的异常。作为开发人员,您可以决定是引发AuraHandledException 异常还是通过引发异常或自定义异常来让异常传播或更好地控制向用户显示的内容 。引发这样的自定义异常:

try {
    // Perform logic that may throw an exception.
} catch (Exception e) {
    throw new MyCustomException('Records could not be retrieved at this time. Try again later');
}

Lightning Web组件和Salesforce数据 模块 中更详细地介绍了处理服务器错误 。

调用Apex以检索过滤的记录

在您创建的accountSearch组件中,让我们检索按提供的员工数量过滤的帐户列表。

    1. 创建一个AccountListControllerLwc Apex类:
      1. 在Visual Studio Code命令面板中,选择(或输入) SFDX:Create Apex Class,然后按 Enter
      2. 输入文件名,AccountListControllerLwc然后按Enter
      3. 接受默认位置(类),然后按 Enter
    2. 用以下代码替换AccountListControllerLwc类的内容:
public with sharing class AccountListControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Account> queryAccountsByEmployeeNumber(Integer numberOfEmployees) {
        return [
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees >= :numberOfEmployees
        ];
   }
}
    1. 保存AccountListControllerLwc类。
    2. 在您的accountSearch.js文件中,通过使用以下代码替换第一行代码,导入wire装饰器和queryAccountsByEmployeeNumberApex方法:
import { LightningElement, wire } from 'lwc';
import queryAccountsByEmployeeNumber from '@salesforce/apex/AccountListControllerLwc.queryAccountsByEmployeeNumber';
  1. 最后,在reset方法之后,添加以下代码:
    @wire(queryAccountsByEmployeeNumber, { numberOfEmployees: '$numberOfEmployees' })
    accounts;
  2. 保存accountSearch.js文件。
  3. 在accountSearch.html文件中的之后<lightning-button>,添加以下代码:
    <template if:true={accounts.data}>
        <template for:each={accounts.data} for:item="account">
             <p key={account.Id}>{account.Name}</p>
        </template>
    </template> 
  4. 保存accountSearch.html文件。
  5. 将AccountListControllerLwc类文件部署到您的Trailhead游乐场:右键单击classes文件夹,然后选择 SFDX:将源部署到Org
  6. 将accountSearch组件文件部署到Trailhead Playground:右键单击accountSearch文件夹,然后选择 SFDX:将源部署到Org
  7. 如果您的Trailhead Playground尚未打开,请打开它。(在命令选项板中,选择(或输入)SFDX:Open Default Org。)
  8. 导航到LWC Visualforce Devs页面并通过在“员工人数”字段中输入值来测试您的组件。当您更改员工人数时,应更新帐户列表。

您只是从Lightning Web组件中的Salesforce组织访问数据。做得好!现在,通过完成动手练习来自己尝试一个。

你可能也会喜欢...