Вы не должны помещать расширенные данные (объекты, массивы, функции) в атрибуты HTML-элементов.Вместо этого предлагается размещать в свойствах только расширенные данные (в соответствии с статьей о лучших практиках пользовательских элементов Google ).Мне нужно выполнить действия, когда эти свойства обновляются.У нас есть observedAttributes
и attributeChangedCallback
, но нет ничего похожего по свойствам.
Допустим, у меня есть user
опора с такими вещами, как name
, DoB
и address
.Я подумал, что смогу обмануть observedAttributes
, поставив установщик койки а-ля
set user(val) {
return;
}
Не сработало.return this.user = val
дает бесконечный цикл.
Моя единственная идея на данный момент - иметь свойство с именем _user
, которое просто устанавливается равным [Object object]
при каждом изменении, которое запускает изменение, которое я на самом деле хочу.Хотя мне это не очень нравится.
ОБНОВЛЕНИЕ : Это то, чем я сейчас занимаюсь
В user-info.js
:
class UserInfo extends HTMLElement {
connectedCallback() {
subscribers.push({ element: this, props: ['user'] });
this._user = state.user;
this.render();
}
static get observedAttributes() {
return ['user'];
}
attributeChangedCallback(name, oldValue, newValue) {
this.render();
}
get user() {
return this._user;
}
set user(val) {
if (JSON.stringify(val) !== JSON.stringify(this._user)) {
this._user = val;
return this.setAttribute('user', val);
}
}
render() {
this.innerHTML = `<span>${this._user.name}</span> was born on <span>${this._user.dob}</span>`;
}
}
В main.js
:
document.querySelector('.actions--user').addEventListener('input', e => {
state.user = {...state.user, [e.target.dataset.action]: e.target.value};
})