Salesforce LWC學習(三十六) Quick Action 支持選擇 LWC了


本篇參考:

https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_quick_actions

https://developer.salesforce.com/docs/component-library/bundle/lightning-quick-action-panel/documentation

背景: 我們現在項目越來越多的使用 lwc 進行了前端開發,當然我們知道lwc並不能所有的場景都支持自己玩,比如組件之間的navigation、 quick action等都需要通過aura進行操作,aura套用lwc來實現。好消息是隨着salesforce的release對lwc的不斷發力,越來越多的功能可以通過lwc來使用。

一. lwc 適配 Quick Action的兩個類型

首先我們先想一下我們通過Aura使用到Quick Action的場景,總結起來可以簡單的歸到2點:

1. 彈出一個popup modal,modal中展示一個UI,不管是一個可以用於修改的表單,還是展示只讀內容然后有操作按鈕等等,這些都無所謂了,重點是有UI的內容,展示modal;

2. 點擊以后執行一個web service或者做一個跳轉操作,用戶不希望彈出來modal,只是希望進行即可。

當然,不同的甲方不同的需求會有不同的實現方案,但是Quick Action當我們選擇 Aura的時候,通常這兩個大的類型就可以搞定的。切回到 lwc,同樣官方也提供了這兩個類似的模式。

  • ScreenAction: 用於聲明一個有popup modal的UI的quick action;
  • Action: 無UI的quick action。

這兩種配置是配置到js-meta.xml里面。配置信息如下:

ScreenAction: 以下的配置是 ScreenAction的配置,主要有幾個點:

  • apiVersion建議選擇52.0,如果有后續的release,當然也可以選擇這個值即以上,目前來講,選擇52.0,嘗試了一下,如果選擇50、51也可以保存,但是為了考慮未知的風險,盡量還是按照規矩來;
  • target設置成 lightning__RecordAction:這個是52 release新有的配置項,需要了解的一點是,如果使用 lwc的quick action,只支持 record 的quick action,global action是不支持的;
  • targetConfig中配置的 actionType為 ScreenAction,當然,如果不配置 targetConfig,默認也是 ScreenAction,所以我們在配置時,默認可以不配置targetConfigs部分;
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
   <apiVersion>52.0</apiVersion>
   <isExposed>true</isExposed>
   <targets>
       <target>lightning__RecordAction</target>
   </targets>
    <targetConfigs>
   <targetConfig targets="lightning__RecordAction">
     <actionType>ScreenAction</actionType>
   </targetConfig>
 </targetConfigs>
</LightningComponentBundle>

Action:和上述的區別只是 actionType為 Action,如果想要選擇 Action類型,則下述所有的內容都無法省略。

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
   <apiVersion>52.0</apiVersion>
   <isExposed>true</isExposed>
   <targets>
       <target>lightning__RecordAction</target>
   </targets>
    <targetConfigs>
   <targetConfig targets="lightning__RecordAction">
     <actionType>Action</actionType>
   </targetConfig>
 </targetConfigs>
</LightningComponentBundle>

 二. ScreenAction的使用

配置篇已經搞定,接下來就搞一下UI,根據官方的demo,我們做一下contact的編輯的一個component quick action。

screenActionSample.js: 主要用於contact的獲取數據以及編輯。這里面有兩個關鍵點。

  • CloseActionScreenEvent是salesforce lwc提供的關閉action的事件,類似於aura的e.force:closeQuickAction。同樣,如果lwc想要關閉,只需要this.dispatchEvent(new CloseActionScreenEvent());即可,類似於aura的$A.get("e.force:closeQuickAction").fire();
  • 我們無法捕捉到X這個關閉按鈕,所以同樣也沒法在這個操作中監聽事件(如果大神們可以監聽到,麻煩告知,我這里在修改)。
import { LightningElement, api, wire,track } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import { updateRecord } from 'lightning/uiRecordApi';
import { CloseActionScreenEvent } from 'lightning/actions';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import FNAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LNAME_FIELD from '@salesforce/schema/Contact.LastName';
import PHONE_FIELD from '@salesforce/schema/Contact.Phone';
import ID_FIELD from '@salesforce/schema/Contact.Id';

const FIELDS = [FNAME_FIELD, LNAME_FIELD, PHONE_FIELD];
export default class screenActionSample extends LightningElement {
    disabled = false;
    @api recordId;
    @api objectApiName;

    contact;

    @track firstName;

    @track lastName;

    @track phone;

    @wire(getRecord, { recordId: '$recordId', fields: FIELDS })
    wiredRecord({ error, data }) {
        if (error) {
            //TODO
        }  else if (data) {
            this.contact = data;
            this.firstName = this.contact.fields.FirstName.value;
            this.lastName = this.contact.fields.LastName.value;
            this.phone = this.contact.fields.Phone.value;
        }
    }

    handleCancel(event) {
       // Add your cancel button implementation here
       this.dispatchEvent(new CloseActionScreenEvent());
    }

    handleChange(event) {
       let source = event.target.name;
       if(source === 'firstName') {
               this.firstName = event.target.value;
       } else if(source === 'lastName') {
               this.lastName = event.target.value;
       } else if(source === 'phone') {
               this.phone = event.target.value;
       }
   }

    handleSubmit(e) {
        // Add your updateRecord implementation
        const fields = {};
        fields[ID_FIELD.fieldApiName] = this.recordId;
        fields[FNAME_FIELD.fieldApiName] = this.firstName;
        fields[LNAME_FIELD.fieldApiName] = this.lastName;
        fields[PHONE_FIELD.fieldApiName] = this.phone;
        const recordInput = { fields };
        console.log(JSON.stringify(recordInput));
        updateRecord(recordInput)
                .then(() => {
                    this.dispatchEvent(
                        new ShowToastEvent({
                            title: 'Success',
                            message: 'Contact updated',
                            variant: 'success'
                        })
                    );
                    this.dispatchEvent(new CloseActionScreenEvent());
                })
                .catch(error => {
                    this.dispatchEvent(
                        new ShowToastEvent({
                            title: 'Error creating record',
                            message: error.body.message,
                            variant: 'error'
                        })
                    );
                });
    }
}

screenAction.html:這里我們看到一個新的組件的面孔: lightning-quick-action-panel。我們查閱官方文檔以后,發現這個使用起來很簡單,就是基於lightning design system中的modal來實現,屬性中可以設置 header屬性,代表action的頭部,slot設置了footer的placeholder。

<template>
    <lightning-quick-action-panel header="Quick Contact Edit">

            <lightning-input label="First Name" name="firstName" value={firstName} class="slds-m-bottom_x-small" onchange={handleChange}></lightning-input>
            <lightning-input label="Last Name" name="lastName" value={lastName} onchange={handleChange} class="slds-m-bottom_x-small" required></lightning-input>
            <lightning-input label="Phone" type="tel" name="phone" value={phone} onchange={handleChange} class="slds-m-bottom_x-small"></lightning-input>

        <div slot="footer">
            <lightning-button variant="neutral" label="Cancel" onclick={handleCancel}></lightning-button>
            <lightning-button variant="brand" class="slds-m-left_x-small" label="Save" type="submit" onclick={handleSubmit} disabled={disabled}></lightning-button>
        </div>
</lightning-quick-action-panel>
</template>

整體展示的效果:

我們來看一下解析的html,這個模型和官方的modal模型是不是很像。

當然,官方除了可以使用 lightning-quick-action-panel組件以外,也支持自己使用html去適配。

三. headless的action效果

headless的action是通過調用 invoke方法來執行,invoke方法前面通過 @api 注解來聲明。如果需要異步操作或者需要訪問后台等在進行操作,可以將方法聲明稱異步,即:@api async invoke() {}

舉一個官方的demo:用來點擊quick action跳轉到 contact list

import { LightningElement, track, wire,api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
export default class headlessActionSAmple extends NavigationMixin(LightningElement) {
    @api invoke() {
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'Contact',
                actionName: 'home',
            },
        });
    }
}

四. 問題思考

 優點: 對於優點來說,太顯而易見了。 基於modal的設計,支持了lwc,還有什么比這個更好的優點嗎

缺點:

1. 和aura彈出modal不同,aura的URL不會改變,lwc會改變URL,兩邊不統一,針對彈出modal以后的刷新操作,lwc加載數據等可能會有潛在的問題,需要測試和適配。舉個例子,上述的ScreenAction的demo,初始化彈出來是正常的,但是當你點擊刷新按鈕或者點擊F5以后,頁面將會進入假死狀態,這種情況可能要考慮一下優化代碼。

 

 


2. lwc彈出的modal的寬度是固定的,如果客戶希望更改lwc彈出的modal的寬度,則無法實現,這種在aura可以通過 aura:tag注入可以搞定
3. 如果基於screen action的modal,目前 lightning-quick-action-panel 還是beta版,項目要求高的,客戶不一定接受。
4. 目前 lwc quick action不支持 salesforce mobile app,有mobile相關的項目,使用前一定要考慮限制,別做完以后電腦端沒有問題,手機端是用不了。

總結:篇中主要介紹lwc如何去適配quick action。篇中有錯誤地方歡迎指出,有不懂歡迎留言。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM