本篇參考:
salesforce零基礎學習(九十五)lightning out
背景: console app,需要在關聯列表展示list button,點選以後進行邏輯。關聯列表並不要求選擇某些資料以後進行操作,只需要獲取父記錄ID即可。比如account詳情頁面有一個 contact關聯列表,需要在 contact關聯列表做一個 contact的list button,這個 contact list button傳參不需要傳選擇的資料(checkbox hide),只需要引數傳遞一下 account id即可。
方案1. 使用 lightning out。 這個當時被我視為了首選方案,不管是後續需求變更,即使傳遞需要選擇的資料也可以遊刃有餘,有途徑來實現。
實現的大概程式碼結構: vf -> lightning app -> lightning component(aura) -> lightning web component(lwc)
具體的業務拋開,目前 lwc只有兩個功能:
1. 點選按鈕展示 toast
2. 點選按鈕關閉當前的 console tab
contactListSampleLwc.html
<template> {accountId} <lightning-button label="show Toast" onclick={handleShowToastEvent}></lightning-button> <lightning-button label="close tab" onclick={handleCloseTabEvent}></lightning-button> </template>
contactListSampleLwc.js
import { LightningElement, track, wire,api } from 'lwc'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; export default class contactListSampleLwc extends LightningElement { @api accountId; handleShowToastEvent(event) { console.log('handle show toast event'); this.dispatchEvent( new ShowToastEvent({ title: 'show toast sample', message: 'show toast message', variant: 'info' }) ); } handleCloseTabEvent(event) { this.dispatchEvent(new CustomEvent('closecurrenttab')); } }
ContactListSampleCmp.cmp
<aura:component implements="force:appHostable" access="global"> <lightning:workspaceAPI aura:id="workspace"/> <aura:attribute name="AccountId" type="String"></aura:attribute> <aura:handler name="init" value="{!this}" action="{!c.handleInit}"/> <c:contactListSampleLwc onclosecurrenttab="{!c.handleCloseCurrentTabEvent}" accountId="{!v.AccountId}"></c:contactListSampleLwc> </aura:component>
ContactListSampleCmpController.js
({ handleCloseCurrentTabEvent : function(component, event, helper) { console.log('execute this current tab handler'); let workspaceAPI = component.find("workspace"); workspaceAPI.getFocusedTabInfo().then(function(response) { var focusedTabId = response.tabId; workspaceAPI.closeTab({tabId: focusedTabId}); }) .catch(function(error) { console.log('execute'); console.log(error); }); }, handleInit : function(component,event,helper) { var workspaceAPI = component.find("workspace"); workspaceAPI.getFocusedTabInfo().then(function(response) { var focusedTabId = response.tabId; workspaceAPI.setTabLabel({ tabId: focusedTabId, label: "Updated Tab Label" }); // workspaceAPI.refreshTab({tabId:focusedTabId}); }) .catch(function(error) { console.log(error); }); // var recordId = component.get("v.pageReference").state.c__RecordId; // component.set('v.AccountId', recordId); } })
ContactListSampleApp.app
<aura:application access="GLOBAL" extends="ltng:outApp"> <aura:dependency resource="c:ContactListSampleCmp"/> </aura:application>
ContactListSamplePage.page
<apex:page standardController="Contact" recordSetVar="Contacts" showHeader="false"> <apex:includeLightning/> <div id="lightning" /> <script> var recordId = '{!$CurrentPage.Parameters.id}'; $Lightning.use("c:ContactListSampleApp", function() { $Lightning.createComponent("c:ContactListSampleCmp", {AccountId : recordId}, 'lightning', function(cmp) { console.log("component created"); } ); }); </script> </apex:page>
配置一下list button,content source選擇Visualforce Page。
遇到的問題:
1. toast 不展示效果
2. close tab 不生效
原因為 lightning out場景下,lwc裡面用標準的一些功能確實好多不支援,懷疑 lightning out使用了一個單獨的 iframe,導致很多標準渲染有問題。既然 lightning out油很多問題,加上我們的需求也不需要選擇selected records,而只是需要獲取account id,那就曲線救國一下。
2. lightning component可以設定 isUrlAddressable, salesforce component navigation可以通過 implements isUrlAddressable 直接訪問,訪問的URL為: /cmp/componentName即可,通過傳遞 c__paramName,aura端就可以獲取到 paramName資訊。
注意一點的是: community cloud貌似不支援c__paramName方式傳遞,所以如果是community專案也有這個功能,慎用。
這裡我們更改兩點。
1. ContactListSampleCmp.cmp的implements增加以下 isUrlAddressable
<aura:component implements="force:appHostable,lightning:isUrlAddressable,force:hasRecordId" access="global">
2. ContactListSampleCmpController.js的handleInit方法,將recordId通過 pageReference獲取的程式碼註釋開啟。
然後設定一下content source修改成URL,然後填上下圖的URL
至此我們重新點選按鈕以後,我們會發現URL其實是跳轉到這個aura上面,所以toast等功能是可以正常使用的。
這裡再額外引申一下workspaceAPI.refreshTab的功能,本來再彈出的情況下,偶爾tab不會更新名稱,所以當時檢視了API在 init方法setLabel以後使用了refreshTab,結果程式死迴圈了,原因是 refreshTab不只是重新整理 tab這個小的區域,這個tab裡面包含的內容將會重新的載入,所以千萬不要在component生命週期中使用refreshTab從而造成死迴圈。
總結:或許是 lightning out用的不熟練,使用lightning out的時候,感覺坑還是一堆。salesforce針對 list button目前在lex環境還是支援的不太友好,有 list button的需求還是要多評估一下,避免入坑。篇中有錯誤歡迎指出,有不懂歡迎留言。