最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

data binding - "Bindable" variables in JavaScript? - Stack Overflow

programmeradmin7浏览0评论

From my littleexperience in Flex, I learned about Bindable variables, so that the content of a text element changed with th value of a variable, for example.

I'm wondering if it's possible to do such a thing in JavaScript. For instance, suppose I have an <h1 id="big_title"> that I want to contain the document's title. That can easily be done with document.getElementById('big_title').innerHTML = document.title;, but what if document.title changes? I'd have to manually update big_title as well.

Another way of putting it, is there a way to create a custom onchange-like event handler on a variable rather than a DOM element? This handler could update the title as needed.

EDIT: I know I could use a setInterval to check for variable "bindings" (defined in an array) and update as needed, but this would be somewhat hack-ish and would require a promise between responsiveness and impact on performance.

From my littleexperience in Flex, I learned about Bindable variables, so that the content of a text element changed with th value of a variable, for example.

I'm wondering if it's possible to do such a thing in JavaScript. For instance, suppose I have an <h1 id="big_title"> that I want to contain the document's title. That can easily be done with document.getElementById('big_title').innerHTML = document.title;, but what if document.title changes? I'd have to manually update big_title as well.

Another way of putting it, is there a way to create a custom onchange-like event handler on a variable rather than a DOM element? This handler could update the title as needed.

EDIT: I know I could use a setInterval to check for variable "bindings" (defined in an array) and update as needed, but this would be somewhat hack-ish and would require a promise between responsiveness and impact on performance.

Share Improve this question edited Sep 25, 2011 at 4:53 Niet the Dark Absol asked Sep 25, 2011 at 4:43 Niet the Dark AbsolNiet the Dark Absol 325k85 gold badges474 silver badges600 bronze badges 5
  • Well you aren't really modifying a variable - you're altering the DOM. As far as I know, you can't bind a DOM element's text to a javascript variable. You could update it whenever javascript events are fired, though. – Rusty Fausak Commented Sep 25, 2011 at 4:48
  • documentcloud.github./backbone – Ilia Choly Commented Sep 25, 2011 at 4:56
  • Thank you for the link, but I would rather have one single simple script rather than require a full framework for just one of its features. – Niet the Dark Absol Commented Sep 25, 2011 at 5:05
  • You could always look at the source. – Jared Farrish Commented Sep 25, 2011 at 5:13
  • I did. Even with all the ments, I can't work out what does what and how to adapt it... – Niet the Dark Absol Commented Sep 25, 2011 at 5:18
Add a ment  | 

3 Answers 3

Reset to default 3

You can "watch" objects in most major browsers. Here is a shim. The idea essentially is to have a setter (in that example it's the function called handler) that will be executed when the value changes. I'm not sure what the extent of browser support is.

Although to be honest it sounds like a much easier solution to have your own setter method. Either make it into an object (you can easily extend this example to use a generic handler insetad of always changing the title):

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"

Or if it isn't something you need to instantiate multiple times, a simple function + convention will do:

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

A simple method is to concentrate the related elements under one Javascript variable. This variable has a setter method and is bound to a user specified handler function that is called when the setter is invoked.

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;
};

The Binder is used as follows:

<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>

The best way:

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

发布评论

评论列表(0)

  1. 暂无评论