この記事では、 オープンソース版 LWC でカスタムワイヤーアダプターを作成し、 @wire デコレータでデータプロビジョンする方法をご紹介します。
オープンソース版 LWC でカスタム Express サーバーの設定方法 で作成したプロジェクトを編集する前提となっています。
ワイヤーアダプター
LWC にはデータサービスとしてワイヤーサービスと呼ばれる、LWC コンポーネントで利用するデータを宣言的に取得するための仕組みが備わっています。
ワイヤーサービスを利用してデータを取得する場合は、ワイヤーアダプターをインスタンス化する必要があり、以下のフォーマットで宣言する事になります。
@wire(adapterId, [config]) wiredProperty|wiredFunction
// @wire: wire デコレータ。config の値に変更があれば wireAdapter に紐づく eventTarget に通知する
// adapterId: データ取得ロジックが実装されたアダプター関数への参照
// config: アダプターを起動する設定。通常はデータ取得のためのパラメータ。
// wiredProperty|wiredFunction: ワイヤー変数、もしくはワイヤー関数。ワイヤー値でプロビジョンされる。
開発者は独自のアダプターを開発し、wire
でデコレートする事であらゆるワイヤーアダプターを作成する事が出来ます。
初めてワイヤーサービスを使う場合
オープンソース LWC で新規に作成したプロジェクトの場合、そのままではワイヤーサービスを利用できません。
ワイヤーサービスを使うには、lwc
モジュールの register
関数と wire-service
モジュールを紐付けておく必要があります。
import { createElement, register} from 'lwc';
import MyApp from 'my/app';
// register 関数を wire-service に登録する
import { registerWireService } from 'wire-service';
registerWireService(register);
const app = createElement('my-app', { is: MyApp });
document.querySelector('#main').appendChild(app);
カスタムワイヤーアダプターを使ったサンプル
このサンプルでは、画面上ので選んだ値をもとに、サーバーから顧客情報を取得、画面にテキストで表示する、というシンプルなコンポーネントを作成しています。
<template>
<select onchange={onSelectChanged}>
<option value="1">1</option>
<option value="2">2</option>
</select>
<p>{contact}</p>
</template>
import {LightningElement, wire} from 'lwc';
import getContact from 'api/getContact';
// Component Class
export default class App extends LightningElement {
// Private Properties
contactId;
// Wired Properties
@wire(getContact, {contactId: '$contactId'}) _contact;
// Getters and Setters
get contact() {
return JSON.stringify(this._contact.data);
}
// Callbacks
renderedCallback() {
const select = this.template.querySelector('select');
this.contactId = select.options[select.selectedIndex].value;
}
// Event Handlers
onSelectChanged(e) {
this.contactId = e.target.value;
}
}
import { register, ValueChangedEvent } from 'wire-service';
// アダプターとなる関数を定義し、エクスポートする
export default function getContact(config) {
if (!config.contactId) return Promise.resolve();
return fetch(`/contact/${config.contactId}`).then(response => response.json());
}
// アダプター関数に紐づくワイヤーアダプターをインスタンス化するためのファクトリー関数を登録する
// ファクトリー関数では、いつ、どんな形式でワイヤー変数/関数をプロビジョンするかを定義しておく
register(getContact, eventTarget => {
// コンポーネントが接続された時
eventTarget.addEventListener('connect', () => {
// ワイヤー変数/関数に初期値をプロビジョンする
eventTarget.dispatchEvent(new ValueChangedEvent({ data: undefined, error: undefined }));
});
// config が変更された時
eventTarget.addEventListener('config', config => {
// 新しい config でワイヤー変数/関数をプロビジョンする
getContact(config)
.then(contact => eventTarget.dispatchEvent(new ValueChangedEvent({ data: contact })))
.catch(error => eventTarget.dispatchEvent(new ValueChangedEvent({error: error})))
});
// コンポーネントが切断された時
eventTarget.addEventListener('disconnect', config => {
// 処理なし
});
});