knockout + knockout-postbox (possible bug)
by rniemeyer
HTML
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
<div id="publish">
<h2>Publish</h2>
<ul data-bind="foreach: items">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.checked" />
<span data-bind="text: name"></span>
</li>
</ul>
<br />
Length of checked observable: <span data-bind="text: checked().length"></span>
<ul data-bind="foreach: checked">
<li data-bind="text: name"></li>
</ul>
</div>
<div id="subscribe">
<h2>Subscribe (subscribes to "names")</h2>
<ul data-bind="foreach: items">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.checked" />
<span data-bind="text: name"></span>
</li>
</ul>
<br />
Length of checked observable: <span data-bind="text: checked().length"></span>
<ul data-bind="foreach: checked">
<li data-bind="text: name"></li>
</ul>
</div>
Instructions:
<ol>
<li>Click "name 3" in the "Subscribe" section</li>
<li>Click "name 1" in the "Publish" section</li>
<li>Notice how observable array for the publishing view model reflects changes in the subscribing view model.</li>
</ol>
CSS
body {
font-family: verdana;
font-size: 12px;
}
h2 {
margin-bottom:10px;
}
div {
margin-bottom: 20px;
padding:10px;
border: 1px solid #ddd;
background-color: #eee;
}
li {
margin-left: 10px;
}
JavaScript
// knockout-postbox 0.4.1 | (c) 2013 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license
!function(a){"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?a(require("knockout"),exports):"function"==typeof define&&define.amd?define(["knockout","exports"],a):a(ko,ko.postbox={})}(function(a,b,c){var d,e;a.subscribable.call(b),b.topicCache={},b.serializer=a.toJSON,b.publish=function(a,c){a&&(b.topicCache[a]={value:c,serialized:b.serializer(c)},b.notifySubscribers(c,a))},e=b.subscribe,b.subscribe=function(a,d,f,g){var h,i;return a?("boolean"==typeof f&&(g=f,f=c),h=e.call(b,d,f,a),g&&(i=b.topicCache[a],i!==c&&d(i.value)),h):void 0},b.defaultComparer=function(a,c){return c&&b.serializer(a)===c.serialized},a.subscribable.fn.publishOn=function(a,c,e){var f;return a&&("function"==typeof c?e=c:f=c,e=e||b.defaultComparer,d.call(this,a,"publishOn"),this.postboxSubs[a].publishOn=this.subscribe(function(c){e.call(this,c,b.topicCache[a])||b.publish(a,c)},this),f||b.publish(a,this())),this},d=function(a,b){var c=this.postboxSubs=this.postboxSubs||{};c[a]=c[a]||{},c[a][b]&&c[a][b].dispose()},a.subscribable.fn.stopPublishingOn=function(a){return d.call(this,a,"publishOn"),this},a.subscribable.fn.subscribeTo=function(e,f,g){var h,i,j,k=this;return"function"==typeof f?g=f:h=f,e&&a.isWriteableObservable(this)&&(d.call(this,e,"subscribeTo"),j=function(a){k(g?g.call(k,a):a)},this.postboxSubs[e].subscribeTo=b.subscribe(e,j),h&&(i=b.topicCache[e],i!==c&&j(i.value))),this},a.subscribable.fn.unsubscribeFrom=function(a){return d.call(this,a,"subscribeTo"),this},a.subscribable.fn.syncWith=function(a,b,c,d){return this.subscribeTo(a,b).publishOn(a,c,d),this},a.postbox=b});
// view model with publishing of checked items
var publishViewModel = {
items: ko.observableArray([{
name: "name 1"
}, {
name: "name 2"
}]),
checked: ko.observableArray().publishOn("names")
};
ko.applyBindings(publishViewModel,...