Call A Function When A Property Gets Set On An Object
Solution 1:
try this example in chrome (as mentioned in previous comments it uses ES6 Proxy):
var p = newProxy(
{},
{
get: function(obj, name) {
console.log('read request to ' + name + ' property');
if (name == 'test_test') return1234;
elsereturn'Meh';
},
set: function(obj, name, value) {
console.log('write request to ' + name + ' property with ' + value + ' value');
},
}
);
console.log(p.test_test);
console.log(p.test);
p.qqq = 'test';
result:
read request to test_test property1234
read request to test property
Meh
write request to qqq propertywith test value
Solution 2:
var test = {};
Object.defineProperty(test, "hello", {
get : function () {
returnthis._hello;
},
set : function (val) {
alert(val);
this._hello = val;
}
});
test.hello = "world";
Something like that. But it will not work on old browsers.
You can find more options here: http://robertnyman.com/javascript/javascript-getters-setters.html
Solution 3:
If you really insist on keeping the test.hello = "world"
syntax to detect changes for existing properties, then you'll have to wait a few years for Object.watch
to become part of the next EcmaScript standard.
Luckily, you can do the same in EcmaScript 5 using Object.defineProperty
. Eli Grey made a nice Object.watch
polyfill which you can call like this:
var test = {};
test.watch("hello", function(propertyName, oldValue, newValue) {
console.log(propertyName + " has been set to " + newValue);
});
test.hello = "world"; // triggers the watch handler
You could modify his code to trigger a different handler inside the getter
as well, so you can detect property accesses.
Unfortunately, browser support is limited to modern browsers including Internet Explorer 9, Firefox 4, Chrome, Opera 12 and Safari 5.
If you want to trigger a handler when a new property is set, you'll have even more trouble. The best you could do is wrapping your object inside a proxy and placing a set
trap. You can then detect whether the property already existed by testing if this.getOwnPropertyDescriptor(name)
returns a 'truthy' value. The Proxy API is very experimental though and only a few browsers provide a prototype implementation to play with. You'll probably have to wait quite a while to get a completed API with decent browser support.
Solution 4:
you need a library that provides key-value observing and bindings.
ember-metal is one such library.
basically you create objects, and you can register observers on properties of those objects.
var obj = Em.Object.create({
val: null
valDidChange:function(){...}.observes('val')
});
valDidChange will fire whenever val
property changes, so
obj.set('val', 'newValue');
will cause the observer to fire.
Solution 5:
What about something like this? Here's a jsfiddle.
var objectManager = function(obj, setCallback){
this.obj = obj;
this.setCallback = setCallback;
};
objectManager.prototype.setProperty = function(prop, value){
this.obj[prop] = value;
this.setCallback(prop);
};
objectManager.prototype.getObj = function(){
returnthis.obj;
};
// USAGE:var testMgr = newobjectManager({}, function(prop){
console.log(name + ' has been set.');
});
testMgr.setProperty("hello", "world"); //should log "hello has been set.";
Post a Comment for "Call A Function When A Property Gets Set On An Object"