【问题标题】:"Bindable" variables in JavaScript?JavaScript中的“可绑定”变量?
【发布时间】:2011-09-25 04:43:06
【问题描述】:

从我对 Flex 的一点经验中,我了解了 Bindable 变量,例如,文本元素的内容会随着变量的值而变化。

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

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

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

【问题讨论】:

  • 嗯,你并没有真正修改变量——你正在改变 DOM。据我所知,您不能将 DOM 元素的文本绑定到 javascript 变量。不过,您可以在触发 javascript 事件时对其进行更新。
  • 感谢您提供的链接,但我宁愿拥有一个简单的脚本,也不愿只为其中一项功能提供完整的框架。
  • 您可以随时查看源代码。
  • 我做到了。即使有所有的cmets,我也无法弄清楚它是做什么以及如何适应它......

标签: javascript data-binding


【解决方案1】:

您可以在大多数主流浏览器中“观看”对象。 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
}

【讨论】:

  • 感谢两位的回答。既然我只能接受一个答案,那就是这个答案,因为它包含单功能选项。
【解决方案2】:

一种简单的方法是将相关元素集中在一个 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>

【讨论】:

    【解决方案3】:

    最好的办法:

     (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 + ')';
    &lt;h1 id="test"&gt;Foo&lt;/h1&gt;

    【讨论】:

      猜你喜欢
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 2011-06-18
      • 2020-02-17
      相关资源
      最近更新 更多