不应该将丰富的数据(对象、数组、函数)放在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};
})发布于 2019-05-01 13:53:39
可以使用代理检测对象的更新属性。
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>
或者,您可以使用与自定义元素交互的设置器定义用户object / class。
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>
https://stackoverflow.com/questions/55932792
复制相似问题