Skip to content

Instantly share code, notes, and snippets.

@Baudin999
Created June 16, 2014 10:13
Show Gist options
  • Save Baudin999/9fd02d7196d136732f80 to your computer and use it in GitHub Desktop.
Save Baudin999/9fd02d7196d136732f80 to your computer and use it in GitHub Desktop.
Notify property changed
define(function () {
var self = this;
self.notifyPropertyChanged = function (obj) {
// initialize the local variables
var args = Array.prototype.slice.call(arguments),
skipList = [];
// test if we have enough paramters in the function call.
if (args.length == 0) throw 'When applying notification on an object you must specify the object as the forst parameter of the function.';
if (args.length == 1) throw 'No changed handler supplied.';
// test if we have a skip-list as second parameter.
if (Object.prototype.toString.call(args[1]) === '[object Array]') {
skipList = args[1];
// if we have a skip list but no other arguments throw an exceptions
if (args.length == 2) throw 'No changed handler supplied.';
}
// map over the enumerable keys
Object.keys(obj).map(function (key) {
// if the key is not in the skipList, add the changed handler.
if (skipList.indexOf(key) == -1) {
// close over the value of the property
var _value = obj[key],
propertyChanged = function (type, value) {
// a reduction variable to propagate information to the next change handler.
var reductionVariable = {};
reductionVariable.type = type;
reductionVariable.continue = true;
args.map(function (changeHandler) {
if (reductionVariable.continue) {
if (changeHandler && Object.prototype.toString.call(changeHandler) === '[object Function]') {
// a handler can but does not have to return the reduction variable.
changeHandler.call(obj, key, value, reductionVariable);
}
}
});
return reductionVariable;
},
afterPropertyChanged = function () {
propertyChanged('afterPropertyChanged', _value);
},
beforePropertyChanged = function (v) {
return propertyChanged('beforePropertyChanged', v);
};
// define a proeprty.
Object.defineProperty(obj, key, {
enumerable: true,
get: function () {
return _value;
},
set: function (value) {
var r = beforePropertyChanged(value);
if (r.continue) {
_value = value;
afterPropertyChanged();
}
}
});
// if the property is an array, notify on splice and push
if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
var _length = _value.length;
setInterval(function () {
if (_length != _value.length) {
_length = _value.length;
afterPropertyChanged();
}
}, 250);
}
}
});
};
return self;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment