高级卡片视图功能
本教程以下列教程为基础: 生成第一个 SharePoint 自适应卡片扩展
重要
此功能在 1.14 版本中仍处于预览状态,不应在生产中使用。 我们正在考虑在即将发布的 1.15 版本中正式发布它们。
在本教程中将实现高级卡视图功能。 你将继续上一教程,并创建一个由 SharePoint 列表中的数据提供支持的卡片视图。
创建测试列表
准备本教程时,在 SharePoint 站点中创建一个包含一些示例数据的新列表:
浏览到网站,并创建名为“指令列表”的新列表。
添加名为 “说明” 的 “单行文本” 列。
将几个项添加到列表中:
- 标题: 步骤 1,说明: 使用 ACE
- 标题: 步骤 2,说明: ???
- 标题: 步骤 3,说明: SPFx 🚀 🌝
获取列表 ID:
查看列表时,选择套件栏中的 齿轮 图标,打开 设置 菜单。 然后选择 “列表设置” 菜单项:
在 “列表设置” 页上,在 URL 中定位列表的 ID:
保存列表的 ID,以便可以在下一步中使用它。
添加 ACE 功能
从上一教程中的 HelloWorld ACE 开始,生成第一个 SharePoint 自适应卡扩展。 在准备步骤 2 时进行以下更新。
更改属性
让我们修改 ACE 的属性,并设置包含 ACE 将显示的数据的列表 ID:
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts。
更新用于定义 ACE 属性类型的接口
properties
:export interface IHelloWorldAdaptiveCardExtensionProps { title: string; description: string; iconProperty: string; listId: string; }
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.manifest.json。
通过设置以下
preConfiguredEntries
,使用上一步骤中创建的列表 ID 初始化 ACE:"preconfiguredEntries": [{ // ... "properties": { "title": "HelloWorld", "description": "HelloWorld description", "iconProperty": "", // Default to sharepointlogo "listId": "" // TODO: enter list id } }]
重要
请确保将之前获取的列表的 ID 输入到上面的
preconfiguredEntries
代码中的listId
属性中。在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/HelloWorldPropertyPane.ts。
通过添加以下字段更新“属性窗格”:
PropertyPaneTextField('listId', { label: 'List ID' })
更改 ACE 的状态
接下来,我们来更新 ACE 的状态。 状态更改时将触发 ACE 进行重新呈现。 这些更改将列表项集合添加到状态以及当前所显示的项目,如你将要添加的 currentIndex
属性所指示。
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts。
通过在文件中添加以下代码,为“列表数据”添加新接口:
export interface IListItem { title: string; description: string; }
更新用于定义 ACE 状态的接口,以使用新的 IListItem 接口:
export interface IHelloWorldAdaptiveCardExtensionState { currentIndex: number; items: IListItem[]; }
通过更新 ACE 中的
onInit()
方法来更新state
初始化:public onInit(): Promise<void> { this.state = { currentIndex: 0, items: [] }; // ... }
通过更新
onPropertyPaneFieldChanged()
方法,暂时删除 ACE 和视图中引用state
的位置:// tslint:disable-next-line: no-any protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void { }
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/quickView/QuickView.ts。
将
data()
和onAction()
方法更新为以下内容:public get data(): IQuickViewData { return { subTitle: '', title: strings.Title }; } public onAction(action: IActionArguments): void { }
现在,状态已更新,我们可以更新 ACE 以从 SharePoint 列表中提取数据。
添加依赖项
下一步是添加对项目和 ACE 的支持,以从 SharePoint 列表检索项目。 为此,你将使用 SharePoint 框架 (SPFx) API 以调用 SharePoint REST 终结点。
首先,向用于向 REST 终结点提交 HTTP 请求的 SPFx 包添加依赖项:
在项目中找到并打开以下文件: ./package.json。 请注意 package.json 文件的
dependencies
节中作为依赖关系的其他软件包所使用的 SPFx 相关的 beta 版。在项目中安装以下 NPM 包:@microsoft/sp-http:
npm install @microsoft/sp-http -SE
提取列表数据
接下来,添加对调用 SharePoint REST API 以及将检索到的项目添加到 ACE 状态的支持。 状态更新时将触发 ACE 进行重新呈现。
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts。
使用 SPFx SPHttpClient API 请求列表数据。 将以下内容添加到实现 ACE 的类:
import { SPHttpClient } from '@microsoft/sp-http'; .. private _fetchData(): Promise<void> { if (this.properties.listId) { return this.context.spHttpClient.get( `${this.context.pageContext.web.absoluteUrl}` + `/_api/web/lists/GetById(id='${this.properties.listId}')/items`, SPHttpClient.configurations.v1 ) .then((response) => response.json()) .then((jsonResponse) => jsonResponse.value.map( (item) => { return { title: item.Title, description: item.Description }; }) ) .then((items) => this.setState({ items })); } return Promise.resolve(); }
通过更新
onInit()
方法,更新 ACE 以在初始化列表数据期间请求列表数据。如下所示,将最后一行
return Promise.resolve();
替换为return this._fetchData();
:public onInit(): Promise<void> { // ... return this._fetchData(); }
更新 ACE,以便在更新属性窗格时请求提供列表数据。 在实现 ACE 类中添加以下方法。 此代码仅在属性窗格中更改列表的 ID 时才请求数据:
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void { if (propertyPath === 'listId' && newValue !== oldValue) { if (newValue) { this._fetchData(); } else { this.setState({ items: [] }); } } }
卡片更新
更新 ACE 以从 SharePoint 列表中提取项目后,我们来更新卡片以显示此数据。
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/cardView/CardView.ts。
更新
data()
getter 以显示列表中的数据:public get data(): IPrimaryTextCardParameters { const { title, description } = this.state.items[this.state.currentIndex]; return { description, primaryText: title }; }
现在可以测试 ACE。 在托管工作台中生成并启动 ACE:
gulp serve
加载本地 Web 服务器后,导航到托管的工作台: https://{tenant}.sharepoint.com/_layouts/15/workbench.aspx
注意
从工作台中删除所有旧的 ACE 实例。 上一教程 中的 ACE 实例将显示一个错误信息,因为 ACE 属性已更新。
打开工具箱并选择 ACE:
条件卡片视图
默认情况下,视图会自动调整卡片的大小。 然而,ACE 可以选择为任何给定卡片的尺寸提供不同的视图。
更改 HelloWorld ACE,以显示 “中等 卡片”大小中的“列表项总数”,并在 大 卡大小中显示“列表项”,以最大程度地使用可用空间。
中型卡片视图
让我们为 ACE 创建一个中型卡片视图:
在文件夹创建一个新文件 ./src/adaptiveCardExtensions/helloWorld/cardView/MediumCardView.ts。
添加以下代码以创建新的 中型 卡视图:
import { BaseBasicCardView, IActionArguments, IBasicCardParameters, ICardButton } from '@microsoft/sp-adaptive-card-extension-base'; import { IListItem, QUICK_VIEW_REGISTRY_ID, IHelloWorldAdaptiveCardExtensionProps, IHelloWorldAdaptiveCardExtensionState } from '../HelloWorldAdaptiveCardExtension'; // Extend from BaseBasicCardView export class MediumCardView extends BaseBasicCardView<IHelloWorldAdaptiveCardExtensionProps, IHelloWorldAdaptiveCardExtensionState> { // Use the Card button to open the Quick View public get cardButtons(): [ICardButton] { return [ { title: 'View All', action: { type: 'QuickView', parameters: { view: QUICK_VIEW_REGISTRY_ID } } } ]; } // Display the total number of steps public get data(): IBasicCardParameters { return { primaryText: `${this.state.items.length} Steps` }; } }
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts。
现在,通过对 ACE 进行以下更改来注册新视图:
import { MediumCardView } from './cardView/MediumCardView'; .. const MEDIUM_VIEW_REGISTRY_ID: string = 'HelloWorld_MEDIUM_VIEW'; .. public onInit(): Promise<void> { // ... this.cardNavigator.register(CARD_VIEW_REGISTRY_ID, () => new CardView()); this.cardNavigator.register(MEDIUM_VIEW_REGISTRY_ID, () => new MediumCardView()); // ... }
更新
renderCard()
方法,以根据卡片大小返回 中等 卡视图或 大型 卡视图:protected renderCard(): string | undefined { return this.cardSize === 'Medium' ? MEDIUM_VIEW_REGISTRY_ID : CARD_VIEW_REGISTRY_ID; }
通过刷新工作台测试更改:
将卡片大小更改为 大型 并刷新浏览器:
大型卡片交互性
ACE 卡视图支持用户交互。 按钮可以调用 REST API,也可以用于通过其他方式与卡片交互。 在本部分中,将更改“大型卡”视图以循环访问 SharePoint 列表中的项。
在项目中定位并打开以下文件: ./src/adaptiveCardExtensions/helloWorld/cardView/CardView.ts。
在文件顶部,将
IActionArguments
添加为要从 @microsoft/sp-adaptive-card-extension-base 包导入的引用之一:import { IActionArguments } from '@microsoft/sp-adaptive-card-extension-base';
卡片视图上的按钮可以根据 ACE 的当前状态进行动态调整。 将以下代码添加到 ACE 的 CardView.ts 文件:
public get cardButtons(): [ICardButton] | [ICardButton, ICardButton] { const buttons: ICardButton[] = []; // Hide the Previous button if at Step 1 if (this.state.currentIndex > 0) { buttons.push({ title: 'Previous', action: { type: 'Submit', parameters: { id: 'previous', op: -1 // Decrement the index } } }); } // Hide the Next button if at the end if (this.state.currentIndex < this.state.items.length - 1) { buttons.push({ title: 'Next', action: { type: 'Submit', parameters: { id: 'next', op: 1 // Increment the index } } }); } return buttons as [ICardButton] | [ICardButton, ICardButton]; }
接下来,通过实现以下方法,在选择按钮时更新
state
:public onAction(action: IActionArguments): void { if (action.type === 'Submit') { const { id, op } = action.data; switch (id) { case 'previous': case 'next': this.setState({ currentIndex: this.state.currentIndex + op }); break; } } }
通过在浏览器中重新加载工作台来测试更改。
卡的第一个实例将显示第一个带有 “下一项” 按钮的列表项:
选择 “下一步” 按钮。 卡片将在列表中显示下一项,并添加 “上一步” 按钮:
选择 “下一个” 按钮,直到到达列表中的最后一项。 卡片将显示列表中的项,并且仅显示“ 上一步 ”按钮:
缓存卡片视图和 ACE 状态
从 SPFx v1.14 开始,AES 具有可配置为存储的客户端缓存层:
- 最新呈现的卡片。
- ACE 的状态。
从缓存的卡片视图呈现
如果存储了最新呈现的卡片,仪表板会在初始化 ACE 之前呈现此缓存的卡片,从而提高感知性能。
可以通过替代以下方法配置此缓存的设置:
protected getCacheSettings(): Partial<ICacheSettings> {
return {
isEnabled: true, // can be set to false to disable caching
expiryTimeInSeconds: 86400, // controls how long until the cached card and state are stale
cachedCardView: () => new CardView() // function that returns the custom Card view that will be used to generate the cached card
};
}
从缓存的 ACE 状态解除冻结
可以通过替代以下方法配置缓存的 ACE 状态子集:
protected getCachedState(state: TState): Partial<TState>;
此方法返回的对象将被序列化并缓存。 默认情况下,不缓存任何状态。 在下次调用 onInit
时,反序列化值将作为 ICachedLoadParameters
的一部分传递到 onInit
public onInit(cachedLoadParameters?: ICachedLoadParameters): Promise<void>;
然后,该值可用于解除冻结新初始化的 ACE 的状态。
结束语
经过该实验后,应熟悉以下内容:
- 更改 ACE 的默认
properties
- 更改 ACE
properties
/state
接口 - 创建和注册卡片视图
- 有条件地呈现卡片视图元素
- 高级卡片视图操作
- 缓存卡片视图和 ACE 状态