はじめに
完璧には出来なかったので、もっと良い案をご存じの方おられましたら教えてください。
やりたかったこと
画面に表示するデータを、同じデータ構造で複数種類保つ必要があったため、クラスに定義して保存するようにしたかった。
だめだったこと
クラスの定義は出来なかった。
シンプルなクラス定義と、匿名クラス定義とやらも試してみたけど上手くいかず。
コードに書いたJavaScriptがそのまま画面に埋め込まれるわけではなく、そこからさらにLWC流に解釈されて
色々動かされてるため、調べた結果がそのまま使えない感じでした。
できたこと
色々な値や関数を定義したオブジェクトを作る関数を用意して、それを擬似的にクラスのような形で扱う。
import getPersons from '@salesforce/apex/TestLWCController.getPersons';
export default class TestLWC extends LightningElement {
// データを取得してくる
async doGetPersons() {
const result = await getPersons();
const persons = this.buildPersons(result);
}
// 取得したデータを、変換後のデータに詰め替える
buildPersons(result) {
let persons = [];
for (personMap of result) {
persons.push(this.buildPerson(personMap));
}
}
// apexから受け取ったデータを、objectに変換する
buildPerson(personMap) {
const person = {
/**
* 名前
* JavaDoc形式にも対応している
*/
name: personMap.name,
age: personMap.age,
height: personMap.height,
weight: personMap.weight,
selfIntroduction: function() {
return '私の名前は' + this.name + '。\r\n'
+ '年齢は' + this.age + '歳だよ。';
}
};
// もし、プロパティの追加や削除、設定された値の変更をしたくない場合はfreezeを使う
// Object.freeze(person);
return person;
}
}
良い点
見るべきところを纏められる。
基本的にはクラスを作ったときの良い点と概ね同じ。
個人的に意外と出来てた点としては、JavaDocを書いたときのようにカーソルホバーをしたら、きちんとそのプロパティのdocが表示されたところ。
※ただし、カンマが手前に来てたらダメだった。
const person = {
/**
* 名前 これは表示される
*/
name : personMap.name,
/**
* 年齢 ←これも表示される
*/
age : personMap.age
/**
* 身長 ←これは表示されない
*/
,height : personMap.height
};
悪い点
freezeをすると値の変更もできなくなってしまう。
しかし、freezeをしなかった場合は以降利用しようとした際にプロパティ名を間違えて書いたとしても、その点に気づけない。(エラーは出ないため)
それと、LWCのhtmlから関数を呼ぶことは出来ないため、間に挟まるgetterが必要になる。
コード例
<template>
<lightning-input>
type="text"
label="自己紹介文"
value={person.selfIntroduction()} <!-- ← エラーになる -->
></lightning-input>
<lightning-input>
type="text"
label="自己紹介文"
value={person.selfIntroduction} <!-- ← 取得出来ないため、空になる -->
></lightning-input>
<lightning-input>
type="text"
label="自己紹介文"
value={selfIntroduction} <!-- ← 表示できる -->
></lightning-input>
</template>
export default class TestLWC extends LightningElement {
person = this.buildPerson();
buildPerson() {
const person = {
name: 'ゆうた',
age: 13,
height: 150,
weight: 45,
selfIntroduction: function() {
return '私の名前は' + this.name + '。\r\n'
+ '年齢は' + this.age + '歳だよ。';
}
};
return person;
}
get selfIntroduction() {
return this.person.selfIntroduction();
}
}