ObservableList
by jimnox
JavaScript
function ObservableList(arr) {
var buffer = arr ? arr.slice(0) : []
Object.defineProperties(this, {
buffer: {
enumerable: false,
writable: false,
value: buffer
},
index: {
enumerable: false,
writable: true,
value: 0
},
observers: {
enumerable: false,
writable: false,
value: []
}
})
this.updateIndexers()
}
ObservableList.defineReactiveGetterSetter = function(target, key, enumerable) {
Object.defineProperty(target, String(key), {
enumerable: enumerable,
configurable: true,
get: function() {
return this.buffer[key]
},
set: function(val) {
this.buffer[key] = val
this.updateIndexers()
this.update()
return val
}
})
}
ObservableList.createMutator = function(name, returnFn) {
return function() {
var result = this.buffer[name].apply(this.buffer, arguments)
this.updateIndexers()
this.update()
return result
}
}
ObservableList.createIterator = function(name) {
return function() {
var args = arguments
var me = this
var ob = {
buffer: [],
update: function() {
ob.buffer.length = 0
// to be optimized LoL
var result = me.buffer[name].apply(me.buffer, args)
ob.buffer.push.apply(ob.buffer, result)
}
}
ob.update()
this.observers.push(ob)
return ob.buffer
}
}
var ObservableListPrototype = {
updateIndexers: function() {
var len = this.buffer.length
var index = this.index
while (index > len) {
delete this[index]
index--
}
// to support `arr[arr.length] = xxx`
// better than nothing -_-"
while (index >= 0 && index <= len) {
ObservableList.defineReactiveGetterSetter(this, index, true)
index++
}
this.index = index
},
toArray: function() {
return this.buffer.slice(0)
},
update: function() {
for (var i = 0, len = this.observers.length; i < len; ++i) {
...