以前弊ブログでグローバル変数を利用したWebパーツ接続の方法を紹介しましたが、SPFx v1.8 で動的データが一般提供となったため現在はこちらの利用が推奨となります。当記事では、できるだけシンプルに動的データ接続のやり方をご紹介します。
以前の記事はこちら
www.micknabewata.com
動的データを利用して何ができるか
SPFxで実装した2つのモジュール間で値の受け渡しができます。Webパーツ間に限らず、拡張機能とWebパーツの間などでもデータをやり取りすることが可能です。例えば・・
- 検索ボックスWebパーツに入力された値に従って検索を行い、検索結果Webパーツに表示する
- 住所一覧Webパーツで選択した住所を地図Webパーツで表示する
などの用途があります。

例:検索ボックスと検索結果
例えば上記の例では、検索ボックスWebパーツと検索結果Webパーツの2つを開発しています。
検索ボックスWebパーツが動的データを生成し、テキストボックスへの入力値を公開しています。検索結果Webパーツは動的データを受け取り、入力値に従ってSharePoint内を検索して表示しています。
入力値の受け渡しはインタラクティブに行われ、画面全体を更新することなく検索結果Webパーツの中身だけが再読み込みされるという挙動になります。
実装方法
テキストボックスへの入力値を表示するだけの非常にシンプルな例をGitHubに公開しました。以下でポイントを解説します。
github.com
動的データを保持するクラスの作成
はじめに、動的データの値を保持するクラスが必要です。Microsoft DocsのサンプルにあるようにWebパーツ自身がこの役割を担うことも可能ですが、コードの可読性という意味ではクラスを分けたほうが良いでしょう。
動的データの値を保持するクラスでは、IDynamicDataCallablesインタフェースを実装する必要があります。getPropertyDefinitionsメソッドでプロパティのデータ型を定義し、getPropertyValueメソッドで動的データの値を返却します。
SampleStringData.ts
import { IDynamicDataPropertyDefinition, IDynamicDataCallables } from '@microsoft/sp-dynamic-data';
export const propertyId = 'sampleStringData';
export default class SampleStringData implements IDynamicDataCallables {
private _value : string;
public getPropertyDefinitions(): ReadonlyArray<IDynamicDataPropertyDefinition> {
return [
{
id: propertyId,
title: 'サンプル文字列型データ'
}
];
}
public getPropertyValue(propId: string): string {
switch (propId) {
case propertyId:
return this._value;
}
throw new Error('プロパティIDが不正です。');
}
public setPropertyValue(value : string)
{
this._value = value;
}
}
動的データを提供するWebパーツの作成
動的データを生成し、公開するWebパーツでは、前述のSampleStringDataクラスのインスタンスを保持し、値のセットとプロパティの更新を行います。動的データの初期化時にthis.context.dynamicDataSourceManager.initializeSourceメソッドを実行し、動的データの更新を行う際はthis.context.dynamicDataSourceManager.notifyPropertyChangedメソッドを実行します。
DataProviderWebPart.ts
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { IPropertyPaneConfiguration } from '@microsoft/sp-property-pane';
import * as strings from 'DataProviderWebPartStrings';
import DataProvider from './components/DataProvider';
import { IDataProviderProps } from './components/IDataProviderProps';
import SampleStringData, { propertyId } from '../../dynamicData/SampleStringData';
export interface IDataProviderWebPartProps {
}
export default class DataProviderWebPart extends BaseClientSideWebPart<IDataProviderWebPartProps> {
private sampleStringData : SampleStringData;
public render(): void {
const element: React.ReactElement<IDataProviderProps > = React.createElement(
DataProvider,
{
stringInputCallBack : this.onStringSearch,
addressInputCallBack : () => {},
phoneNumberInputCallBack : () => {}
}
);
ReactDom.render(element, this.domElement);
}
private onStringSearch = (value : string) => {
this.sampleStringData.setPropertyValue(value);
this.context.dynamicDataSourceManager.notifyPropertyChanged(propertyId);
}
protected onInit(): Promise<void> {
this.sampleStringData = new SampleStringData();
this.context.dynamicDataSourceManager.initializeSource(this.sampleStringData);
return Promise.resolve();
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
]
};
}
}
動的データを利用するWebパーツの作成
公開されている動的データを利用するには、動的データの選択を行うためにWebパーツのプロパティを構成する必要があります。Webパーツのプロパティ名をプロパティウィンドウ定義の設定値と一致させる必要があることに注意してください。
DataViewerWebPart.ts
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart, PropertyPaneDynamicFieldSet, PropertyPaneDynamicField, DynamicDataSharedDepth, IWebPartPropertiesMetadata } from '@microsoft/sp-webpart-base';
import { IPropertyPaneConfiguration } from '@microsoft/sp-property-pane';
import * as strings from 'DataViewerWebPartStrings';
import DataViewer from './components/DataViewer';
import { IDataViewerProps } from './components/IDataViewerProps';
import { DynamicProperty } from '@microsoft/sp-component-base';
import { propertyId } from '../../dynamicData/SampleStringData';
export interface IDataViewerWebPartProps {
sampleStringData : DynamicProperty<string>;
}
export default class DataViewerWebPart extends BaseClientSideWebPart<IDataViewerWebPartProps> {
public render(): void {
let dString : string = (this.properties.sampleStringData)? this.properties.sampleStringData.tryGetValue() : undefined;
const element: React.ReactElement<IDataViewerProps > = React.createElement(
DataViewer,
{
string : dString
}
);
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
groups: [
{
groupName : '動的データ接続',
groupFields : [
PropertyPaneDynamicFieldSet({
label : '動的データ接続',
fields : [
PropertyPaneDynamicField(
propertyId,
{
label : '接続先'
}
)
],
sharedConfiguration : {
depth : DynamicDataSharedDepth.Property
}
})
]
}
]
}
]
};
}
}
以上、参考になれば幸いです。