Salesforce LWC學習(七) Navigation & Toast

上一篇咱們介紹了針對LWC中經常使用的LDS的適配的wire service以及@salesforce模塊提供的相關的service,其實LWC中還提供其餘的好用的service,好比針對導航相關的lightning/navigation以及展現toast提示信息相關的lightning/platformShowToastEvent。此篇主要針對這兩個service進行簡單的介紹。javascript

一. lightning/navigationhtml

咱們有好多場景會用到跳轉操做,好比建立記錄之後跳轉到此記錄詳情頁,點擊鏈接跳轉到下載頁面或者直接下載文件,跳轉到某個列表等等。LWC中封裝了lightning/navigation service去實現相關的跳轉操做。固然,此service除了封裝了跳轉相關的功能,還封裝了獲取當前PageReference的功能。詳情以下所示。java

1. CurrentPageReference:此方法用於獲取當前頁面的引用,使用如下的聲明即可以獲取到當前的頁面的引用了。若是咱們想編輯其鍵值對的parameter,咱們須要更新當前page reference的Page state。至於如何更新,下面會有介紹。api

1 import { CurrentPageReference } from 'lightning/navigation';
2 @wire(CurrentPageReference)
3 pageRef;

返回的pageRef爲PageReference變量。PageReference爲js封裝的對象,有三個變量。
1) type:當前PageReference的類型。lwc封裝瞭如下的類型:app

  • Lightning Component
  • Knowledge Article
  • Login Page
  • Named Page
  • Navigation Item Page
  • Object Page
  • Record Page
  • Record Relationship Page
  • Web Page

這些PageReference詳情能夠參看:https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_page_reference_type
咱們經常使用的有Lightning Component / Object Page / Record Page / Record Relationship Page / Web Page。
2)attribute:聲明不一樣類型的PageReference建立PageReference須要配置不一樣的attribute,細節的attribute的配置同看上面連接。ide

3)state:用來存儲鍵值對類型的parameter。咱們在URL中可能傳遞參數,使用CurrentPageReference獲取到的PageReference中,state存儲的即是其參數部分。學習

下面來一個demo更好的瞭解用法以及返回內容。this

getCurrentPageReferenceDemo.js:裝載CurrentPagReference,將引用賦值給pageRef;
 1 import { LightningElement, wire } from 'lwc';
 2 import {CurrentPageReference} from 'lightning/navigation';
 3 export default class GetCurrentPageReferenceDemo extends LightningElement {
 4     @wire(CurrentPageReference)
 5     pageRef;
 6 
 7     get currentPageInfo() {
 8         if(this.pageRef !== undefined) {
 9             return JSON.stringify(this.pageRef);
10         }
11         return '';
12     }
13 }

getCurrentPageReferenceDemo.html:url

1 <template>
2     {currentPageInfo}
3 </template>

顯示結果:咱們將此component放在contacts的詳情頁裏面,而且針對詳情頁的URL手動設置了parameter,返回的結果以下圖所示。spa

 2. NavigationMixin:使用此adapter實現跳轉功能。此adapter封裝了兩個API實現跳轉。

  • [NavigationMixin.Navigate](pageReference, [replace]) - 在應用中一個component調用此API跳轉到另一個頁面;
  • [NavigationMixin.GenerateUrl](pageReference) - component調用此API獲取須要跳轉的URL的Promise。

這兩個API,先調用GenerateUrl獲取到Promise,而後使用Navigate的API便可實現跳轉。咱們使用此service前須要先在頭引入,和其餘的區別爲咱們還須要在javascript的class中去繼承NavigationMixin。

import { NavigationMixin } from 'lightning/navigation';
export default class MyCustomElement extends NavigationMixin(LightningElement) {}

上面的兩個API咱們也能夠看見pageReference參數,此參數和上面的CurrentPageReference返回值類型相同,均爲javascript中封裝的CurrentPageReference對象。咱們可使用plain object去拼接此對象的變量。說的比較繞,下面經過一個官方的demo即可以更好的瞭解。

 navigationLineExample.js:在connectedCallback生命週期處聲明瞭PageReference的Promise,用於handleClick時去觸發。

 1 import { LightningElement, track } from 'lwc';
 2 import { NavigationMixin } from 'lightning/navigation';
 3 
 4 export default class NavigationLinkExample extends NavigationMixin(LightningElement) {
 5     @track url;
 6 
 7     connectedCallback() {
 8         // Store the PageReference in a variable to use in handleClick.
 9         // This is a plain Javascript object that conforms to the
10         // PageReference type by including "type" and "attributes" properties.
11         // The "state" property is optional.
12         this.accountHomePageRef = {
13             type: "standard__objectPage",
14             attributes: {
15                 "objectApiName": "Account",
16                 "actionName": "home"
17             }
18         };
19         this[NavigationMixin.GenerateUrl](this.accountHomePageRef)
20             .then(url => this.url = url);
21     }
22 
23     handleClick(evt) {
24         // Stop the event's default behavior.
25         // Stop the event from bubbling up in the DOM.
26         evt.preventDefault();
27         evt.stopPropagation();
28         // Navigate to the Account Home page.
29         this[NavigationMixin.Navigate](this.accountHomePageRef);
30     }
31 }

navigationLineExample.html:點擊按鈕觸發handleClick方法

1 <template>
2     <div>
3         <a href={url} onclick={handleClick}>Account Home</a>
4     </div>
5 </template>

將demo配置在account的record page中,經過上面的demo咱們即可以實現跳轉到Account的home頁面的功能,也能夠看到聲明 PageReference中的type以及attributes的神奇之處。原理了解之後只須要經過改變PageReference Type以及其對應的attribute咱們即可以實現更多的功能,感興趣的小夥伴能夠自行嘗試。

 咱們在跳轉或者自刷新時,有時須要傳遞參數,在LWC中上面也提到過使用state變量傳遞參數,咱們在更新此變量前先了解一下相關的限制和要求。

  • pagereference對象已凍結,所以不能直接更改它。若是咱們想要跳轉到一個一樣的頁面而且這個頁面包含了已經更新了的state,咱們須要copy一下當前的這個PageReference而後使用Object.assign({}, pageReference)方式去更新state,若是跳轉到不一樣的頁面,咱們只須要建立plain PageReference的時候傳進去便可,就不會有此點所說的限制。
  • state變量在構建鍵值對時,鍵必須使用namespace加上兩個下劃線__做爲前綴,若是不是managed package,則namespace爲c,好比咱們想要傳遞testParam的值爲testValue。則構建鍵值對應該爲state.c__testParam = testValue;
  • state變量中的鍵值對的value必須所有爲string類型由於state變量的鍵值對都可以序列化到URL query parameter。
  • 若是想要刪除state的某個鍵值對,只須要設置value爲undefined便可。

經過上述1,2,3,4點咱們能夠看出來,1屬於限制,2,3,4屬於規範。咱們針對跳轉到其餘頁面直接設置state便可,若是針對跳轉到當前頁面,只是參數變化,便須要考慮上面的第一點。經過官方提供的demo能夠更好的瞭解針對parameter的處理。

 pageStateChangeExample.js:demo中考慮的時跳轉到當前頁面,只是參數的變化的處理。此時pagereference已經凍結,只能經過Object.assign方法去處理。

 1 import { LightningElement, wire, track } from 'lwc';
 2 import { CurrentPageReference, NavigationMixin } from 'lightning/navigation';
 3 
 4 export default class PageStateChangeExample extends NavigationMixin(LightningElement) {
 5 
 6     // Injects the page reference that describes the current page
 7     @wire(CurrentPageReference)
 8     setCurrentPageReference(currentPageReference) {
 9         this.currentPageReference = currentPageReference;
10 
11         if (this.connected) {
12             // We need both the currentPageReference, and to be connected before
13             // we can use NavigationMixin
14             this.generateUrls();
15         } else {
16             // NavigationMixin doesn't work before connectedCallback, so if we have 
17             // the currentPageReference, but haven't connected yet, queue it up
18             this.generateUrlOnConnected = true;
19         }
20     }
21     @track
22     showPanelUrl;
23 
24     @track
25     noPanelUrl;
26 
27     // Determines the display for the component's panel
28     get showPanel() {
29         // Derive this property's value from the current page state
30         return this.currentPageReference &&
31             this.currentPageReference.state.c__showPanel == 'true';
32     }
33 
34     generateUrls() {
35         this[NavigationMixin.GenerateUrl](this.showPanelPageReference)
36             .then(url => this.showPanelUrl = url);
37         this[NavigationMixin.GenerateUrl](this.noPanelPageReference)
38             .then(url => this.noPanelUrl = url);
39     }
40 
41     // Returns a page reference that matches the current page
42     // but sets the "c__showPanel" page state property to "true"
43     get showPanelPageReference() {
44         return this.getUpdatedPageReference({
45             c__showPanel: 'true' // Value must be a string
46         });
47     }
48 
49     // Returns a page reference that matches the current page
50     // but removes the "c__showPanel" page state property
51     get noPanelPageReference() {
52         return this.getUpdatedPageReference({
53             // Removes this property from the state
54             c__showPanel: undefined
55         });
56     }
57 
58     // Utility function that returns a copy of the current page reference
59     // after applying the stateChanges to the state on the new copy
60     getUpdatedPageReference(stateChanges) {
61         // The currentPageReference property is read-only.
62         // To navigate to the same page with a modified state,
63         // copy the currentPageReference and modify the copy.
64         return Object.assign({}, this.currentPageReference, {
65             // Copy the existing page state to preserve other parameters
66             // If any property on stateChanges is present but has an undefined
67             // value, that property in the page state is removed.
68             state: Object.assign({}, this.currentPageReference.state, stateChanges)
69         });
70     }
71 
72     connectedCallback() {
73         this.connected = true;
74         
75         // If the CurrentPageReference returned before this component was connected,
76         // we can use NavigationMixin to generate the URLs
77         if (this.generateUrlOnConnected) {
78             this.generateUrls();
79         }
80     }
81 
82     handleShowPanelClick(evt) {
83         evt.preventDefault();
84         evt.stopPropagation();
85         // This example passes true to the 'replace' argument on the navigate API
86         // to change the page state without pushing a new history entry onto the
87         // browser history stack. This prevents the user from having to press back
88         // twice to return to the previous page.
89         this[NavigationMixin.Navigate](this.showPanelPageReference, true);
90     }
91 
92     handleNoPanelClick(evt) {
93         evt.preventDefault();
94         evt.stopPropagation();
95         this[NavigationMixin.Navigate](this.noPanelPageReference, true);
96     }
97 }

pageStateChangeExample.html:針對showPanel以及noPanelUrl的處理

<template>
    <div>
        <a href={showPanelUrl} onclick={handleShowPanelClick}>Show Panel</a>
    </div>
    <div if:true={showPanel}>
        <h1>This is the panel</h1>
        <a href={noPanelUrl} onclick={handleNoPanelClick}>Hide Panel</a>
    </div>
</template>

 二. Lightning/platformShowToastEvent

當咱們進行DML操做或者某種場景或者validation須要展現一些信息,固然咱們能夠經過ligtning-messages展現信息在頁面上,另一種方式可使用toast方式僅顯示幾秒的提示信息隨後消失的樣式。LWC提供了lightning/platformShowToastEvent實現此功能。模塊中封裝了ShowToastEvent事件,實例化之後dispatchEvent便可使用。

ShowToastEvent事件有如下的幾個參數

  • title:toast的標題部分,展現在header區域;
  • message:toast的內容部分。此message能夠是一個純文本,也能夠是一個包含place holder的文本,place holder一般是URL或者文本;
  • messageData:當message中包含{} place holder時,使用messageData進行替換;
  • variant:toast中展現的theme以及icon的樣式。有幾個值供選擇:info / success / warning / error。咱們能夠根據不一樣的場景顯示不一樣的variant進行展現;
  • mode:用來決定toast展現多長時間。有幾個值供選擇:dismissable/pester/sticky。dismissable是默認的值,功能爲用戶點擊關閉按鈕或者通過3秒之後toast消失;pester用於只顯示3秒,3秒之後自動消失(此種沒有關閉按鈕);sticky用於只有用戶點擊關閉按鈕纔會消失。

咱們在recordEditFormSample展現此用法。

 1 <template>
 2     <lightning-record-edit-form
 3         record-id={recordId}
 4         object-api-name={objectApiName}
 5         onsubmit={handleSubmit}
 6         onload={handleLoad}
 7         onsuccess={handleSuccess}
 8         onerror={handleError}
 9         >
10         <lightning-messages></lightning-messages>
11         <lightning-input-field field-name="Name"></lightning-input-field>
12         <lightning-input-field field-name="Industry"></lightning-input-field>
13         <lightning-input-field field-name="AnnualRevenue"></lightning-input-field>
14         <div class="slds-m-top_medium">
15             <lightning-button class="slds-m-top_small" label="Cancel" onclick={handleReset}></lightning-button>
16             <lightning-button class="slds-m-top_small" type="submit" label="Save Record"></lightning-button>
17         </div>
18     </lightning-record-edit-form>
19 </template>

recordEditFormSample.js

 1 /* eslint-disable no-console */
 2 import { LightningElement, api } from 'lwc';
 3 import { ShowToastEvent } from 'lightning/platformShowToastEvent';
 4 export default class RecordEditFormSample extends LightningElement {
 5 
 6     @api recordId;
 7     @api objectApiName;
 8 
 9     handleSubmit(event) {
10         event.preventDefault();       // stop the form from submitting
11         const fields = event.detail.fields;
12         if(fields.Industry === null || fields.Industry === '') {
13             const evt = new ShowToastEvent({
14                 title: "Account Operated Failed",
15                 message: "Account Industry cannot be blank",
16                 variant: "error",
17                 mode:"pester"
18             });
19             this.dispatchEvent(evt);
20             return;
21         }
22         this.template.querySelector('lightning-record-edit-form').submit(fields);
23     }
24 
25     handleLoad(event) {
26         console.log('execute load');
27     }
28 
29     handleSuccess(event) {
30         const evt = new ShowToastEvent({
31             title: "Account Operated Success",
32             message: "Record is :" + event.detail.id,
33             variant: "success"
34         });
35         this.dispatchEvent(evt);
36     }
37 
38     handleError(event) {
39         const evt = new ShowToastEvent({
40             title: "Account Operated Failed",
41             message: event.detail.message,
42             variant: "error",
43             mode: "sticky"
44         });
45         this.dispatchEvent(evt);
46     }
47 
48     handleReset(event) {
49         const inputFields = this.template.querySelectorAll(
50             'lightning-input-field'
51         );
52         if (inputFields) {
53             inputFields.forEach(field => {
54                 field.reset();
55             });
56         }
57      }
58 }

效果展現:

 sticky樣式,只有點擊關閉按鈕才能消失toast。

 

 總結:此篇主要說的是Navigation以及Toast相關的知識,其中Navigation能夠根據不一樣的type以及attribute去作不一樣功能的跳轉以及下載等操做,篇中例舉的比較少,感興趣的能夠深刻學習。篇中有錯誤地方歡迎指出,有不懂的歡迎留言。

相關文章
相關標籤/搜索