I go for data-binding using ECMA7 Object.observe
or Mozilla Object.watch
instead of eventEmitter
of node.
For Object.observe
, I cannnot find any implementation around for android browser compatiblity. They basically must use setTimeout polling, so I gave up.
Instead, Object.watch
can run without any polling with a library for Chrome, and natively Firefox etc.
The code I found is
if (!Object.prototype.watch)
{
Object.defineProperty(Object.prototype, "watch",
{
enumerable: false,
configurable: true,
writable: false,
value: function(prop, handler)
{
var
oldval = this[prop],
newval = oldval,
getter = function()
{
return newval;
},
setter = function(val)
{
oldval = newval;
return newval = handler.call(this, prop, oldval, val);
};
if (delete this[prop])
{ // can't watch constants
Object.defineProperty(this, prop,
{
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
}
});
}
// object.unwatch
if (!Object.prototype.unwatch)
{
Object.defineProperty(Object.prototype, "unwatch",
{
enumerable: false,
configurable: true,
writable: false,
value: function(prop)
{
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
}
});
}
This works with
obj.watch('foo',
function(id, oldval, newval)
{
//..........
return newval;
});
However, a big problem occurs, which is, when I implement multiple watch in various places, the only first obj.watch is triggered, and never for the rest.
The reason is obvious.
On the first trigger, the rest obj.watch is automatically set to watch the changed value.
Test code:
var obj = {
foo: 5
};
obj.watch('foo',
function(id, oldval, newval)
{
alert(newval);
return newval;
});
obj.watch('foo',
function(id, oldval, newval)
{
alert(newval);
return newval;
});
obj.foo = 7;
Result: no error, but alerted only once.
Actually, I try to find alternative library/mechanism that allow to trigger multiple watch-blocks for the same object instance/property.
Again, I will avoid eventEmitter pattern but observer pattern. Do you have any idea? Thanks.
Self Answer.
not sure yet, but one way is to use
melanke/Watch.JS/ https://github.com/melanke/Watch.JS/ that I have known this for a long time.
It does job:
http://jsfiddle.net/NbJuh/62/