Last active
August 29, 2015 14:01
-
-
Save jpiccari/e811d02b4eda69edfb74 to your computer and use it in GitHub Desktop.
An improved observer that tracks changes to existing object properties while still allowing native object access. Should be supported in IE8+, Firefox, Chrome, Safari, etc. (235 bytes minified, gzipped)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define( | |
'observer', | |
[ | |
'EventEmitter' | |
], | |
function(EventEmitter) { | |
'use strict'; | |
var OBSERVER_KEY = '_isObserver', | |
isStandardDefineProperties = true; | |
try { | |
Object.defineProperties(new Object(), {}); | |
} catch(e) { | |
// Must be IE8, we'll have to use a DOM Object :\ | |
isStandardDefineProperties = false; | |
} | |
function defineProperties(object, options) { | |
if (!isStandardDefineProperties) { | |
object = document.createElement('div'); | |
} | |
return Object.defineProperties(object, options); | |
} | |
return function observer(object) { | |
var properties = {}, | |
options = {}, | |
eventKeys = {}, | |
key; | |
options[OBSERVER_KEY] = { | |
value: true, | |
writeable: false | |
}; | |
for (key in object) { | |
if (typeof object[key] === 'object') { | |
object[key] = observer(object[key]); | |
eventKeys[key] = object[key]; | |
} | |
properties[key] = object[key]; | |
options[key] = (function(key) { | |
return { | |
get: function() { | |
return properties[key]; | |
}, | |
set: function(value) { | |
if (value !== properties[key]) { | |
if (typeof value === 'object' && !value[OBSERVER_KEY]) { | |
value = observer(value); | |
} | |
var change = { | |
type: 'updated', | |
object: this, | |
name: key, | |
oldValue: properties[key], | |
value: value | |
}; | |
properties[key] = value; | |
this.trigger('change', change); | |
} | |
} | |
}; | |
}(key)); | |
} | |
object = EventEmitter(defineProperties(object, options)); | |
for (key in eventKeys) { | |
eventKeys[key].on('change', function(change) { | |
change.name = key + '.' + change.name; | |
object.trigger('change', change); | |
}); | |
} | |
return object; | |
}; | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment