本机Web组件中的双向数据绑定

时间:2014-11-10 14:05:21

标签: html5 web-component 2-way-object-databinding

我一直在阅读网络组件,并且对新生规范非常感兴趣。有没有人知道在DOM中是否支持双向数据绑定,而不必使用Polymer?一个例子将不胜感激。

4 个答案:

答案 0 :(得分:4)

Object.observe是一种在javascript中进行数据绑定的潜在新方法。此功能计划用于Ecmascript 7(javascript),但有些浏览器目前支持它,请检查here。另请查看有关object.observe

的这篇html5rocks文章

答案 1 :(得分:2)

不,数据绑定不是Web组件规范的一部分。

您当然可以使用本机JavaScript event listeners以及可能的Proxy对象自行实现数据绑定,但最好不要重新发明轮子:如果您想要数据绑定,请选择一个那些支持它的许多JavaScript框架。 Polymer,React,Angular和Vue是这类库的最新例子。

答案 2 :(得分:0)

一种方式:$ 0上的$0.model = {data};设置器分配$ 0.data,以响应更新,另一种方式:$1.dispatchEvent(new CustomEvent('example', {detail: $1.data, cancelable: true, composed: true, bubbles: true}));$0.addEventListenever('example', handler)给出两种方式的数据绑定。数据对象是相同的,在2个元素上共享,事件和设置器允许响应更新。为了拦截对对象的更新,代理工作model = new Proxy(data, {set: function(data, key, value){ data[key] = value; ...respond... return true; }})other techniques。这解决了简单的情况。您也可以考虑阅读和阅读Redux的资源,它提供了似乎比较流行的约定。正如Ajedi32所提到的那样,除非在学术上有兴趣,否则在更复杂的情况下重新发明轮子是不切实际的。

答案 3 :(得分:0)

最近几天我一直在玩这个游戏。您可以创建一个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>

fiddle here

我喜欢这种方法,因为它直接发生在您要与之通信的元素之间,而无需遍历即可找到data-属性或其他任何东西。