Observer/Observable example in javascript
by spoike
HTML
<ul class="log">
<li class="head">
Log entries
</li>
</ul>
CSS
ul.log {
padding: 10px;
background-color: #efefef;
font-family: Arial, sans-serif;
}
ul.log li {
padding: 10px;
background-color: #fff;
border-top: dashed black thin;
}
ul.log li.head {
font-weight: bold;
border-top: none;
}
JavaScript
var log = function(entry) {
$log = $('ul.log');
$log.append('<li>' + entry + '</li>');
};
var observable = function(v) {
var val = v, subscribers = [];
// the observable object
var output = {
// subscribes to event
onChange : function(func) {
subscribers.push(func);
return output; // enables chaining
},
// the method that changes the observable object
// and emits the event
set : function(v) {
var i;
val = v;
for (i = 0; i < subscribers.length; i++) {
// this is hardly fault tolerant but as long
// as subscribers are functions it'll work
subscribers[i](v);
}
return output;
},
// the method emits an event with given message,
// useful when the observable is a complex
// object
emit : function(msg) {
var i;
for (i = 0; i < subscribers.length; i++) {
subscribers[i](msg, output);
}
return output;
},
// removes subscription
off : function(func) {
// idiomatic JS for removing objects in array
var index = subscribers.indexOf(func);
subscribers.splice(index, 1);
return output;
}
};
return output;
};
// the subject
var component = {
leet : observable(1336),
cat : observable("kitty!")
};
// example of a callback that is removable
var removableFunc = function(v) {
log("{ <b><i>this function will be removed</i></b> }");
}
// Usage (on variables):
component.leet.onChange(function(v) {
log("leet has changed to: " + v);
}).
onChange(function(v) {
log("and it was leet");
});
component.cat.onChange(function(v) {
log("cat has changed to: " + v);
}).onChange(function(v) {
log("and it was awesome");
}).onChange(removableFunc);
component.leet.set(1337);
component.cat.set("cats!");
component.cat.off(removableFunc);
component.cat.set("kitties!");
// Usage (on component-wide updates)
// the subject, the component itself
var...