Improved semaphore
Semaphore that can be used for resources, e.g. ajax requests. Uses ko.postbox as a pub/sub framework so allows semaphores across view-models to update together.
by nickkell
HTML
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.debug.js"></script>
<script src="http://cloud.github.com/downloads/rniemeyer/knockout-postbox/knockout-postbox.js"></script>
<p data-bind="text:semaphore.queued"></p>
<input type="button" value="add" data-bind="click: add" />
<input type="button" value="remove" data-bind="click: remove" />
<div data-bind="if: sub">
<p data-bind="text:sub().semaphore.queued"></p>
</div>
<input type="button" value="add submodel" data-bind="click: addSub" />
<input type="button" value="reset" data-bind="click: semaphore.reset" />
<p data-bind="text: ko.toJSON($root)"></p>
JavaScript
function Semaphore() {
var self = this,
length = ko.observable(0),
add = function(n) {
length(length() + 1);
},
remove = function() {
if (length() > 0) {
length(length() - 1);
}
};
ko.postbox.subscribe('semaphore.add', function(n) {
add();
});
ko.postbox.subscribe('semaphore.remove', function(n) {
remove();
});
ko.postbox.subscribe('semaphore.synch', function(n) {
if ($.isNumeric(n)) {
length(n);
}
});
self.queued = ko.computed(function() {
return length() > 0;
});
self.count = function() {
return length();
};
}
function Sub() {
var self = this;
self.semaphore = new Semaphore();
}
function Model() {
var self = this;
self.semaphore = new Semaphore();
self.sub = ko.observable();
self.add = function() {
ko.postbox.publish('semaphore.add');
};
self.remove = function() {
ko.postbox.publish('semaphore.remove');
};
self.addSub = function() {
self.sub(new Sub());
ko.postbox.publish('semaphore.synch', self.semaphore.count());
};
}
ko.applyBindings(new Model());