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去作不一样功能的跳转以及下载等操做,篇中例举的比较少,感兴趣的能够深刻学习。篇中有错误地方欢迎指出,有不懂的欢迎留言。

相关文章
相关标签/搜索