Как наблюдать изменения свойств с LitElement
Я не знаю, как наблюдать изменения свойств в 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")
}
3 ответа
Я нашел решение из комплектов PWA от Polymer.
Добавьте следующее к определению вашего элемента:
_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);
Параметр свойства hasChanged:
Вы можете определить эту опцию hasChanged в объявлении свойства в геттере статических свойств. Так же, как и с опцией "тип".
hasChanged должен вернуть true, чтобы обновить элемент.
myProp: { hasChanged(newVal, oldVal) {
// compare newVal and oldVal
// return `true` if an update should proceed
}}
Проверить это здесь
Метод жизненного цикла: обновлено
Существует метод жизненного цикла с именем "обновленный", который запускается каждый раз при изменении любого свойства.
Этот метод получает в качестве параметров "changedProperties" с их предыдущими значениями, чтобы вы могли сравнить их с текущими значениями, а затем решить, что вы хотите с ними делать.
Ознакомьтесь с "обновленной" документацией здесь.
Я лично переопределяю метод requestUpdate, чтобы быть в курсе изменений перед рендерингом.
Мой вариант использования - перехватить изменение атрибута "label" для запуска асинхронного запроса данных.
Фрагмент ниже (в 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;
}
}
Таким образом, мой элемент отображается только дважды: один с новой меткой и загрузкой как true, а другой - когда данные доступны.
LitElement автоматически перерисовывает каждый раз, когда изменяется свойство, если это свойство определено в вашем методе _render.
Это отмечено в readme LitElement:
Реакция на изменения: LitElement реагирует на изменения свойств и атрибутов путем> асинхронного рендеринга, гарантируя пакетирование изменений. Это снижает накладные расходы и> поддерживает согласованное состояние.
Например:
_render({firstName, lastName}) {
return html`
<div> Hello ${firstName} ${lastName} </div>
`;
Будет перерисовываться каждый раз при изменении свойств firstName и lastName. Я надеюсь, что это обеспечивает немного ясности.
Реализуйте метод shouldUpdate(). Источник здесь.
Управляет продолжением обновления. Воплощать в жизнь
shouldUpdate
чтобы указать, какие изменения свойств должны вызывать обновления. По умолчанию этот метод всегда возвращает true.
function shouldUpdate(changedProperties: Map<any, any>) {
changedProperties.forEach((oldValue, propName) => {
const newValue = JSON.stringify(this[propName]);
console.log(`${propName} changed. oldValue: ${oldValue} newValue: ${newValue}`);
});
return true;
}