gpt4 book ai didi

javascript - Web 组件 : Is there an equivalent to attributeChangedCallback for properties?

转载 作者:行者123 更新时间:2023-11-30 14:03:11 27 4
gpt4 key购买 nike

您不应该在 HTML 元素属性中放置丰富的数据(对象、数组、函数)。相反,建议仅将丰富的数据放入属性中(根据 Google custom elements best practices article )。我需要在更新这些属性时运行操作。我们有 observedAttributesattributeChangedCallback,但属性没有任何相似之处。

假设我有一个 user Prop ,上面有 nameDoBaddress 之类的东西。我想我可以通过放置一个 bunk setter a la

来欺骗 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};
})

最佳答案

您可以使用 Proxy检测对象的更新属性。

customElements.define( 'user-info', class extends HTMLElement {
connectedCallback() {
this._user = {
name: 'Bruno',
dob: '1/1/2000'
}
this.render();
this._proxy = new Proxy( this._user, {
set: ( obj, prop, val ) => {
if ( prop === 'name' )
if ( this._user.name !== val ) {
console.log( 'username updated to ' + val )
this._user.name = val
this.render()
}
}
} )
}
get user() {
return this._proxy
}
set user(val) {
if (JSON.stringify(val) !== JSON.stringify(this._user)) {
this._user = val
this.render()
}
}
render() {
this.innerHTML = `<span>${this._user.name}</span> was born on <span>${this._user.dob}</span>`
}
} )
<user-info id=ui></user-info><br>
<label>Name: <input oninput="ui.user.name=this.value"></label>


或者,您可以使用可与自定义元素交互的 setter 定义用户 对象/类

class User {
constructor( elem ) {
this._elem = elem
this._name = 'Bruno'
this._dob = '1/1/2000'
}
set name( val ) {
if ( val !== this._name ) {
this._name = val
this._elem.render()
}
return false
}
get name() {
return this._name
}
get dob() {
return this._dob
}
update( obj ) {
this._name = obj.name
this._dob = obj.dob
}
}

class UserInfo extends HTMLElement {
connectedCallback() {
this._user = new User( this )
this.render()
}
get user() {
return this._user
}
set user(val) {
this._user.update( val )
this.render()
}
render() {
this.innerHTML = `<span>${this._user.name}</span> was born on <span>${this._user.dob}</span>`
}
}

customElements.define( 'user-info', UserInfo )
<user-info id=ui></user-info><br>
<label>Name: <input oninput="ui.user.name=this.value"></label>

关于javascript - Web 组件 : Is there an equivalent to attributeChangedCallback for properties?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55932792/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com