Skip to content

Instantly share code, notes, and snippets.

@thefringeninja
Created June 10, 2014 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thefringeninja/e49794697e28c7294c50 to your computer and use it in GitHub Desktop.
Save thefringeninja/e49794697e28c7294c50 to your computer and use it in GitHub Desktop.
Undo with Knockout and Eventing
class window.Bus
constructor: ->
@dispatcher = {}
subscribe: (pattern, handler) ->
handlers = @dispatcher[pattern] || []
handlers.push handler
@dispatcher[pattern] = handlers
publish: (e) ->
for pattern, handlers of @dispatcher when new RegExp(pattern).test e.type
for handler in handlers || []
handler(e)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div data-bind="with: person">
The name is <span data-bind="text: name"></span>
</div>
<div data-bind="with: command">
<form data-bind="submit: submit">
<input type="text" data-bind="value: name" ><button type="submit">Submit</button><button data-bind="click: undo">Undo</button>
</form>
</div>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script type="text/javascript">
window.Bus = (function() {
Bus.name = 'Bus';
function Bus() {
this.dispatcher = {};
}
Bus.prototype.subscribe = function(pattern, handler) {
var handlers;
handlers = this.dispatcher[pattern] || [];
handlers.push(handler);
return this.dispatcher[pattern] = handlers;
};
Bus.prototype.publish = function(e) {
var handler, handlers, pattern, _ref, _results;
_ref = this.dispatcher;
_results = [];
for (pattern in _ref) {
handlers = _ref[pattern];
if (new RegExp(pattern).test(e.type)) {
_results.push((function() {
var _i, _len, _ref1, _results1;
_ref1 = handlers || [];
_results1 = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
handler = _ref1[_i];
_results1.push(handler(e));
}
return _results1;
})());
}
}
return _results;
};
return Bus;
})();
</script>
<script type="text/javascript">
(function(ko, bus){
var eventLog = [];
var vm = {
person: {
name: ko.observable()
},
command: {
name: ko.observable(),
submit: function(){
bus.publish({type: "nameChanged", name: this.name()});
},
undo: function() {
var events = eventLog.slice(0, -1);
eventLog.length = 0;
events.forEach(function(e){
bus.publish(e);
});
}
}
};
bus.subscribe("nameChanged", function(e){
vm.person.name(e.name);
});
bus.subscribe("_init", function(){
vm.person.name("");
});
bus.subscribe(".*", function(e){
eventLog.push(e);
});
ko.applyBindings(vm);
bus.publish({type: "_init"});
})(ko, new window.Bus());
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment