我一直在阅读有关 Web 组件的内容,并且对新生规范非常感兴趣。有谁知道DOM中是否支持2路数据绑定,而不必使用Polymer?一个例子将不胜感激。
4 回答
Object.observe 是一种在 javascript 中进行数据绑定的潜在新方法。此功能计划用于 Ecmascript 7(javascript),但目前一些浏览器支持它,请查看此处。另请查看有关 object.observe 的html5rocks文章
在过去的几天里,我一直在玩这个。您可以创建一个 StateObserver 类,并从中扩展您的 Web 组件。一个最小的实现看起来像这样:
// create a base class to handle state
class StateObserver extends HTMLElement {
constructor () {
super()
StateObserver.instances.push(this)
}
stateUpdate (update) {
StateObserver.lastState = StateObserver.state
StateObserver.state = update
StateObserver.instances.forEach((i) => {
if (!i.onStateUpdate) return
i.onStateUpdate(update, StateObserver.lastState)
})
}
}
StateObserver.instances = []
StateObserver.state = {}
StateObserver.lastState = {}
// create a web component which will react to state changes
class CustomReactive extends StateObserver {
onStateUpdate (state, lastState) {
if (state.someProp === lastState.someProp) return
this.innerHTML = `input is: ${state.someProp}`
}
}
customElements.define('custom-reactive', CustomReactive)
class CustomObserved extends StateObserver {
connectedCallback () {
this.querySelector('input').addEventListener('input', (e) => {
this.stateUpdate({ someProp: e.target.value })
})
}
}
customElements.define('custom-observed', CustomObserved)
<custom-observed>
<input>
</custom-observed>
<br />
<custom-reactive></custom-reactive>
我喜欢这种方法,因为它直接发生在您想要与之通信的那些元素之间,没有 dom 遍历来查找data-
属性或其他任何东西。
一种方式:$0.model = {data};
$0 上的 setter 分配 $0.data,响应更新,另一种方式:$1.dispatchEvent(new CustomEvent('example', {detail: $1.data, cancelable: true, composed: true, bubbles: true}));
with$0.addEventListenever('example', handler)
提供 2 路数据绑定。数据对象是相同的,在 2 个元素上共享,事件和设置器允许响应更新。为了拦截对对象的更新,代理工作model = new Proxy(data, {set: function(data, key, value){ data[key] = value; ...respond... return true; }})
或其他技术。这解决了简单的场景。你也可以考虑查看和阅读 Redux 的源代码,它提供了看起来比较流行的约定。正如 Ajedi32 提到的那样,为更复杂的场景重新发明轮子并不是那么实际,除非它是一种学术兴趣。