LitElementでプロパティの変更を監視する方法がわかりません。
私はこれらの方法を試してきましたが、これらを機能させることができませんでした:
static get properties() {
return {
temp1:String,
temp2: {
type:String,
observer: '_temp2Changed'
}
};
temp1Changed(newValue, oldValue){
console.log("temp1 changed")
}
_temp2Changed(newValue, oldValue){
console.log("temp2 changed")
}
PolymerのPWAスターターキットからソリューションを見つけました。
以下を要素定義に追加します。
_propertiesChanged(props, changed, oldProps) {
console.log("_propertiesChanged(props, changed, oldProps):");
console.log(props);
console.log(changed);
console.log(oldProps);
if (changed && 'temp1' in changed) {
console.log("if temp1:"+changed.temp1);
}
super._propertiesChanged(props, changed, oldProps); //This is needed here
}
console output:
_propertiesChanged(props, changed, oldProps):
{temp1: "newVal1", temp2: "val2"}
{temp1: "newVal1"}
{temp1: "val1"}
if temp1:newVal1
バージョン0.6.0 +
まず、要素のプロパティを指定する必要があります。これを行うには、キーとしての名前と属性関連の構成を含むオブジェクトを返す静的ゲッターを作成します。
updated
ライフサイクルメソッドは、変更されたプロパティが再レンダリングを引き起こしたときに呼び出されます。最初の引数は、更新前の値を返します。
class MyComponent extends LitElement {
static get properties() {
return {
foo: {}
};
}
constructor() {
super();
this.foo = 0;
setInterval(() => this.foo++, 1000);
}
updated(changedProperties) {
console.log(changedProperties); // logs previous values
console.log(this.foo); // logs current value
}
render() {
return html`${this.foo}`;
}
}
customElements.define("my-component", MyComponent);
レンダリングの前に変更を認識できるように、「requestUpdate」メソッドを個人的にオーバーライドしています。
私のユースケースは、「ラベル」属性の変更をインターセプトして非同期データ要求をトリガーすることです。
以下のスニペット(TypeScript):
@customElement('my-element')
export default class MyElement extends LitElement {
@property({type: String})
label: string | null = null;
@property({attribute: false})
private isLoading: boolean = false;
@property({attribute: false, noAccessor: true})
private data: MyData | null = null;
protected render() {/*some code*/}
requestUpdate(name?: PropertyKey, oldValue?: unknown) {
if(name && name == "label" && this.label !== oldValue) {
this.isLoading = true;
requestData(this.label, this._callbackData);
}
return super.requestUpdate(name, oldValue);
}
private _callbackData(data: MyData}) {
this.data = data;
this.isLoading = false;
}
}
このようにして、私の要素は2回だけレンダリングされます。1つは新しいラベルとtrueとしてロードされ、もう1つはデータが利用可能なときにロードされます。
LitElementは、プロパティが '_render'メソッドで定義されている限り、プロパティが変更されるたびに自動的に再レンダリングします。
これはLitElement readme に記載されています:
変更に反応する:LitElementは、非同期レンダリングによってプロパティと属性の変更に反応し、変更がバッチ処理されるようにします。これにより、オーバーヘッドが削減され、一貫した状態が維持されます。
例えば:
_render({firstName, lastName}) {
return html`
<div> Hello ${firstName} ${lastName} </div>
`
};
FirstNameおよびlastNameプロパティが変更されるたびに再レンダリングします。これが少し明確になることを願っています。
プロパティ 'hasChanged'オプション:
この「hasChanged」オプションは、静的プロパティゲッター内のプロパティ宣言で定義できます。 'type'オプションと同じように。
要素を更新するには、hasChangedがtrueを返す必要があります。
myProp: { hasChanged(newVal, oldVal) {
// compare newVal and oldVal
// return `true` if an update should proceed
}}
チェックアウト ここ
ライフサイクルメソッド:更新されました
プロパティが変更されるたびにトリガーされる「updated」というライフサイクルメソッドがあります。
このメソッドは、パラメータとして 'changedProperties'を以前の値と一緒に受け取るので、それらを現在の値と比較して、それで何をしたいかを決定できます。
「更新された」ドキュメントをチェックしてください ここ 。