JavaScript中的“可绑定”变量?

时间:2011-09-25 04:43:07

标签: javascript data-binding

根据我在Flex中的经验,我了解了Bindable变量,例如,文本元素的内容随变量的值而变化。

我想知道是否可以在JavaScript中执行此类操作。例如,假设我有<h1 id="big_title">我想要包含文档的标题。这可以通过document.getElementById('big_title').innerHTML = document.title;轻松完成,但如果document.title发生变化会怎样?我还必须手动更新big_title

另一种方法是,有没有办法在变量而不是DOM元素上创建自定义onchange - 类似的事件处理程序?此处理程序可以根据需要更新标题。

编辑:我知道我可以使用setInterval来检查变量“绑定”(在数组中定义)并根据需要进行更新,但这有点像hack-ish并且需要在响应性和对绩效的影响。

3 个答案:

答案 0 :(得分:3)

您可以在大多数主流浏览器中“观看”对象。 Here是一个垫片。这个想法本质上是有一个setter(在那个例子中它是名为handler的函数),它将在值发生变化时执行。我不确定浏览器支持的范围是什么。

虽然说实话,拥有自己的setter方法听起来更简单。将其变为对象(您可以轻松扩展此示例以使用始终更改标题的通用handler insetad):

function Watchable(val) { // non-prototypal modelling to ensure privacy
   this.set = function(v){
      document.title=val=v;
   };
   this.get = function(){return val;};
   this.set(val);
}

var title = new Watchable("original title");

title.get(); // "original title"
title.set("second title"); // "second title"
title.get(); // "second title"

或者如果它不是你需要多次实例化的东西,那么一个简单的函数+约定就可以了:

function changeVal(newVal) {
   variableToWatch = newVal;
   // change some DOM content
}

答案 1 :(得分:0)

一种简单的方法是将相关元素集中在一个Javascript变量下。此变量具有setter方法,并绑定到用户指定的处理函数,该函数在调用setter时调用。

function Binder(handler) {
    this._value = 0; // will be set 
    this._handler = handler;
}
Binder.prototype.set = function(val) {
    this._value = val;
    this._handler(this);
};
Binder.prototype.get = function() {
    return this._value;
};

Binder使用如下:

<h1 id="h1">Title 0</h1>
<h2 id="h2">Title 0</h2>
<script type="text/javascript">
function titleHandler(variable) {
    var val = variable.get();
    document.getElementById("h1").innerHTML = val;
    document.getElementById("h2").innerHTML = "Sub" + val;
    document.title = val;
}
var title = new Binder(titleHandler);
title.set("Title 2");
</script>

答案 2 :(得分:0)

最好的方法:

&#13;
&#13;
 (function (win) {
   function bindCtrl(id, varName) {
     var c = win.document.getElementById(id);
     if (!varName) varName = id;
     if (c) {
       Object.defineProperty(win, varName, {
         get: function () { return c.innerHTML; },
         set: function (v) { c.innerHTML = v; }
       });
     }

     return c;
   }

   win.bindCtrl = bindCtrl;
})(this);

// Bind control "test" to "x" variable
bindCtrl('test', 'x');

// Change value
x = 'Bar (prev: ' + x + ')';
&#13;
<h1 id="test">Foo</h1>
&#13;
&#13;
&#13;