普通Javascript双向数据绑定 [英] Plain Javascript bidirectional Data binding
问题描述
出于好奇,增加我的知识,我想在dom元素和javascript变量之间实现某种双向数据绑定。
out of curiosity and to increase my knowledge, i wanted to implement some kind of two way data binding between dom elements and javascript variables.
我很幸运找到一个很好的答案,我的一半问题在这里@ stackoverflow,这导致我这个想法 https://gist.github.com / 384583 ,但我仍然无法完成100%的事情。
I was lucky enough to find an excellent answer to half of my problem here @ stackoverflow which led me to this gist https://gist.github.com/384583, but i still can't get the thing done at 100%.
这是一个我的代码示例:
http://jsfiddle.net/bpH6Z/
如果您尝试运行小提琴并单击查看值,您将获得未定义,同时我想获取对象属性的实际值。
If you try to run the fiddle and click on "view Value" you will get undefined, while i want to get the actual value of the object's attribute.
由于我缺乏JavaScript的经验,我可能会做错事,但是你有什么想法,为什么我不能正确地读取_bind()和_watch之后的属性secret )电话?
I am probably doing something wrong due to my lack of experience with javascript, but do you have any idea why i can't properly read the attribute 'secret' after the _bind() and _watch() calls?
免责声明:正如我所说,我是这样做的,因为我想要更好地了解javascript,我不会写我的框架。所以任何使用框架X都是完全没用的,因为我可以使用angularjs完成这项工作。
DISCLAIMER: as i said, i'm doing this because i want better knowledge of javascript, and i am not going to write my framework. So any "USE FRAMEWORK X" is completely useless, as i could get the job done with angularjs.
推荐答案
请尝试 http://jsfiddle.net/bpH6Z/4/
我已经在Object.prototype .__手表中更新了您重定义的getter / setter,
目前您的处理程序需要返回新值。
I've updated your redefined getter/setter in Object.prototype.__watch, also currently your handler needs to return the new value.
更新:现在您的处理程序不需要返回新设置的值。
Update: Now your handler isn't required to return the newly set value.
当前代码:
//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>
这篇关于普通Javascript双向数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!