Created
July 26, 2013 14:37
-
-
Save FireNeslo/6089356 to your computer and use it in GitHub Desktop.
Observer like object to maintain a reference to data that can or will change a lot.
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
/** | |
Creates a new Objserver. | |
@class Observes an object and updates its value on changes that are applied. | |
@param [value] - Optional init value; - | |
*/ | |
function Objserver(value) { | |
this.$value = value; | |
this.$change = []; | |
} | |
function jsonPath(obj,string) { | |
var parts = string | |
.replace(/\[/g, '.') | |
.replace(/\]/g, '') | |
.split("."), | |
path = obj; | |
parts.forEach(function(part){ | |
path = path[part]; | |
}); | |
return path; | |
} | |
/** | |
* @memberOf Objserver | |
* Adds a change listener that is fired if somthing changes | |
* @returns {Objserver} self - For chaining | |
*/ | |
Objserver.prototype.onChange = function(cb) { | |
this.$change.push(cb); | |
return this; | |
}; | |
/** | |
* @memberOf Objserver | |
* @param {function} listener - Listener to remove. | |
* @returns {Objserver} self - For chaining | |
*/ | |
Objserver.prototype.off = function(cb) { | |
this.$change.splice(this.$change.indexOf(cb), 1); | |
return this; | |
}; | |
/** | |
* Trigger change event | |
* @memberOf Objserver | |
* @param newval - The new value | |
* @param newval - The old value | |
* @returns {Objserver} self - For chaining | |
*/ | |
Objserver.prototype.change = function(newval, oldval) { | |
var _self = this; | |
this.$change.forEach(function(fn, index) { | |
var $event = { | |
class : Objserver, | |
instance : _self, | |
value : _self.$value | |
}; | |
fn.call($event, newval, oldval); | |
}); | |
return this; | |
}; | |
/** | |
* Get current value | |
* @memberOf Objserver | |
* @returns value current value | |
*/ | |
Objserver.prototype.val = function() { | |
return this.$value; | |
} | |
/** | |
* Bind the value to some object to keep that object informed on updates. | |
* @memberOf Objserver | |
* @param {object} object - Object to bind to | |
* @param {string} name - Attribute name | |
* @returns {Objserver} self - For chaining | |
*/ | |
Objserver.prototype.bind = function(object, name) { | |
object[name] = this.$value; | |
this.change(function(value) { | |
object[name] = value; | |
}); | |
return this; | |
}; | |
/** | |
* Maps function on object, native map fo arrays or unboxing for promises | |
* @memberOf Objserver | |
* @param {function} fn - The function to map. | |
* @returns {Objserver} self - For chaining | |
*/ | |
Objserver.prototype.map = function(fn) { | |
var _self = this; | |
if(this.$value.then) { | |
_self.$value.then(function(value) { | |
_self.ap(fn); | |
}) | |
} | |
var newVal = this.$value.map(fn), oldVal = this.$value; | |
this.$value = newVal; | |
this.change(newVal, oldVal); | |
return this; | |
}; | |
/** | |
* Map / Apply method | |
* @memberOf Objserver | |
* @param {function|Promise|object} cb - The Object/Promise or function to apply. | |
* @param {string} jsonpath - the path to the value you supplied. | |
* @returns {Objserver} self - For chaining | |
*/ | |
Objserver.prototype.ap = function(cb,jsonpath) { | |
var _self = this, | |
oldVal, | |
newVal; | |
if(this.$value && this.$value.then) { | |
_self.$value.then(function(value) { | |
_self.$value = value; | |
_self.ap(cb); | |
}); | |
} else if(cb && cb.then) { | |
oldVal = this.$value; | |
cb.then(function(value) { | |
newVal = jsonpath ? | |
jsonPath(value, jsonpath) : | |
value; | |
_self.$value = newVal; | |
_self.change(newVal, oldVal); | |
}); | |
} else if(!angular.isFunction(cb)) { | |
oldVal = _self.$value; | |
newVal = jsonpath ? | |
jsonPath(cb, jsonpath) : | |
cb; | |
_self.$value = newVal; | |
this.change(newVal, oldVal); | |
} else { | |
oldVal = this.$value; | |
newVal = cb(this.$value); | |
this.$value = newVal; | |
this.change(newVal, oldVal); | |
} | |
return this; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment