作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您不应该在 HTML 元素属性中放置丰富的数据(对象、数组、函数)。相反,建议仅将丰富的数据放入属性中(根据 Google custom elements best practices article )。我需要在更新这些属性时运行操作。我们有 observedAttributes
和 attributeChangedCallback
,但属性没有任何相似之处。
假设我有一个 user
Prop ,上面有 name
、DoB
和 address
之类的东西。我想我可以通过放置一个 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/
我是一名优秀的程序员,十分优秀!