So here's a quick example (see attachment for full example and below the content of "observable.js" file from it)
Role('JooseX.Observable.Attribute', {
override : {
getSetter : function () {
var original = this.SUPER()
// here "this" is the attribute instance
var me = this
return function (value) {
var prevValue = me.getValueFrom(this) // or just this[ me.slot ] for simple cases
// here - "this" is the instance of class that has this attribute
var result = original.apply(this, arguments)
this.fireEvent(
me.name + 'change', value, prevValue)
return result
}
}
}
})
Role('JooseX.Observable.Class', {
does : [
JooseX.Observable
],
trait : Role({
has : {
defaultAttributeClass : Class({ does : JooseX.Observable.Attribute, isa : Joose.Managed.Attribute })
}
})
})
Class('My.Observable.Class', {
does : JooseX.Observable.Class,
has : {
attribute : {
// to create getter/setter
is : 'rw'
}
}
})
var instance = new My.Observable.Class({
attribute : 1
})
instance.on('attributechange', function (event, newValue, oldValue) { console.log("handler works, new value = " + newValue + ", old value = " + oldValue) })
instance.setAttribute(2)
1) we created a special role for attribute JooseX.Observable.Attribute', so this feature can be combined with other features.
- does "JooseX.Observable" so any class consuming that role will also does that role
- has a "trait" - role that will be applied to the meta-class of the consuming class. This trait just changes the default attribute class to the new attribute class (that does our JooseX.Observable.Attribute)
3) Setters are not used during initial instance construction, so the event will never be emited for that.