"Bindable" variables in JavaScript?
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 开发者_StackOverflowcreate 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 compromise between responsiveness and impact on performance.
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>
精彩评论