纯Javascript双向数据绑定
Posted
技术标签:
【中文标题】纯Javascript双向数据绑定【英文标题】:Plain Javascript bidirectional Data binding 【发布时间】:2012-08-07 21:30:07 【问题描述】:出于好奇和增加知识,我想在 dom 元素和 javascript 变量之间实现某种双向数据绑定。
我很幸运在这里 @*** 找到了解决我一半问题的绝佳答案,这使我找到了这个要点 https://gist.github.com/384583,但我仍然无法 100% 完成任务。
这是一个我的代码示例: http://jsfiddle.net/bpH6Z/
如果您尝试运行 fiddle 并单击“查看值”,您将得到 undefined,而我想获取对象属性的实际值。
由于我缺乏使用 javascript 的经验,我可能做错了什么,但您知道为什么在 _bind() 和 _watch() 调用之后我无法正确读取属性“秘密”吗?
免责声明:正如我所说,我这样做是因为我想要更好地了解 javascript,并且我不会编写我的框架。所以任何“使用框架 X”都是完全没用的,因为我可以用 angularjs 完成工作。
【问题讨论】:
ist $ 指的是 jQuery 吗?所以这不是普通的 JS 呵呵 How to Implement DOM Data Binding in JavaScript的可能重复 【参考方案1】:您传递给__watch
函数的处理程序缺少return
语句。
this._watch = function(DOMelement, propertyName)
//__watch triggers when the property changes
this.__watch(propertyName, function(property, value)
$(DOMelement).val(value);
return value;
)
因为 newval
设置为从处理程序返回的内容,所以如果没有它,它将是 undefined
。
【讨论】:
+1。当场,击败我......我终于也注意到了这一点【参考方案2】:请尝试http://jsfiddle.net/bpH6Z/4/
我已经更新了您在 Object.prototype.__watch 中重新定义的 getter/setter, 目前您的处理程序也需要返回新值。
更新:现在您的处理程序不需要返回新设置的值。
当前代码:
//Got this great piece of code from https://gist.github.com/384583
Object.defineProperty(Object.prototype, "__watch",
enumerable: false,
configurable: true,
writable: false,
value: function(prop, handler)
var val = this[prop],
getter = function()
return val;
,
setter = function(newval)
val = newval;
handler.call(this, prop, newval);
return newval;
;
if (delete this[prop]) // can't watch constants
Object.defineProperty(this, prop,
get: getter,
set: setter,
enumerable: true,
configurable: true
);
);
var Controller = function ()
//The property is changed whenever the dom element changes value
//TODO add a callback ?
this._bind = function (DOMelement, propertyName)
//The next line is commented because priority is given to the model
//this[propertyName] = $(DOMelement).val();
var _ctrl = this;
$(DOMelement).on("change input propertyChange", function(e)
e.preventDefault();
_ctrl[propertyName] = DOMelement.val();
);
;
//The dom element changes values when the propertyName is setted
this._watch = function(DOMelement, propertyName)
//__watch triggers when the property changes
this.__watch(propertyName, function(property, value)
$(DOMelement).val(value);
);
;
;
var ctrl = new Controller();
ctrl.secret = 'null';
ctrl._bind($('#text1'), 'secret'); // I want the model to reflect changes in #text1
ctrl._watch($('#text2'), 'secret'); // I want the dom element #text2 to reflect changes in the model
$('#button1').click(function()
$('#output').html('Secret is : ' + ctrl.secret); //This gives problems
);
当前 HTML:
<html>
<head></head>
<body>
value: <input type="text" id="text1" /><br />
copy: <input type="text" id="text2" /><br />
<input type="button" id="button1" value="View value"><br />
<span id="output"></span>
</body>
</html>
【讨论】:
这是否适用于 IE8,因为 defineProperty 仅适用于 DOM 对象? @Integralist 很可能不会,但应该试一试 - 必须重新启动到 xp【参考方案3】:我已针对多人观看者进行了增强。
http://jsfiddle.net/liyuankui/54vE4/
//The dom element changes values when the propertyName is setted
this._watch = function(DOMelement, propertyName)
//__watch triggers when the property changes
if(watchList.indexOf(DOMelement)<0)
watchList.push(DOMelement);
this.__watch(propertyName, function(property, value)
for(var i=0;i<watchList.length;i++)
var watch=watchList[i];
$(watch).val(value);
$(watch).html(value);
);
;
【讨论】:
以上是关于纯Javascript双向数据绑定的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript实现简单的双向数据绑定(EmberAngularVue)
JavaScript实现简单的双向数据绑定(EmberAngularVue)
JavaScript实现简单的双向数据绑定(EmberAngularVue)