prototype inheritance and knockoutjs
by gene
HTML
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<script src="https://raw.github.com/mbest/knockout-deferred-updates/master/knockout-deferred-updates.js"></script>
<table border="3" cellpadding="2">
<tr>
<td>
<div data-bind="template: {name: 'list', data: {list: docList, item: 'doctemplate'}}"></div>
</td>
<!-- ko foreach: postingSets -->
<td>
<div data-bind="template: {name: 'list', data: {list: $data, item: 'postingtemplate'}}"></div>
</td>
<!-- /ko -->
</tr>
</table>
<button data-bind="click: runQuery">Query</button>
<script id="list" type="text/html">
<div data-bind="foreach: list">
<div class="item" data-bind="template: {data: $data, name: $parent.item}"></div>
</div>
</script>
<script id="doctemplate" type="text/html">
<div>
<span data-bind="text: docid"></span>
<span data-bind="text: title"></span>
</div>
<div>Retrieved <span data-bind="text: retrievedCount"></span> times</div>
</script>
<script id="postingtemplate" type="text/html">
<div>
#<span data-bind="text: rank"></span>
<span data-bind="text: title"></span>
</div>
<div>Retrieved <span data-bind="text: retrievedCount"></span> times</div>
</script>
CSS
.document {
display: inline;
margin-right: 10px;
text-decoration: none;
}
body {
font-family: sans-serif;
font-size: 10pt;
}
.lists > li {
cursor: pointer;
}
.pageButton {
border: 1px solid blue;
margin: 4px;
display: inline;
padding: 2px;
width: 10px;
height: 10px;
cursor: pointer;
}
.items {
padding: 6px;
border: 1px solid grey;
margin: 6px;
}
.item {
margin-bottom: 6px;
}
td {
padding: 6px;
width:150px;
}
JavaScript
function Document(id, title) {
var self = this;
this.docid = ko.observable(id);
this.title = ko.observable(title);
this.history = ko.observableArray([]);
this.retrievedCount = ko.computed(function() {
return self.history().length;
});
}
var postingId = 1;
function Posting(rank) {
var self = this;
this.id = ko.observable(postingId++);
this.rank = ko.observable(rank);
this.__proto__.history.push(this);
return this;
}
var id = 1;
var docs = [
new Document(id++, 'first doc'),
new Document(id++, 'second doc'),
new Document(id++, 'third doc'),
new Document(id++, 'fourth doc'),
new Document(id++, 'fifth doc'),
new Document(id++, 'sixth doc'),
new Document(id++, 'seventh doc'),
new Document(id++, 'eighth doc'),
new Document(id++, 'ninth doc'),
new Document(id++, 'tenth doc'),
/* new Document(id++, 'eleventh doc'),
new Document(id++, 'twlevth doc'),
new Document(id++, 'thirteenth doc'),
new Document(id++, 'fourteenth doc'),
new Document(id++, 'fifteenth doc'),
new Document(id++, 'sixteenth doc'),
new Document(id++, 'seventeenth doc'),
new Document(id++, 'eighteenth doc'),
new Document(id++, 'nineteenth doc'),
new Document(id++, 'twentieth doc') */
];
function PostingFactory(index, rank) {
Posting.prototype = docs[index];
return new Posting(rank);
}
function viewModel() {
var self = this;
this.docList = ko.observableArray(docs);
this.postingSets = ko.observableArray([]);
this.runQuery = function() {
var n = Math.floor(Math.random()*10+1);
var postings = ko.observableArray([]);
for (var i=0; i<n; i++) {
var index = Math.floor(Math.random()*docs.length);
postings.push( PostingFactory(index, i+1) );
}
self.postingSets.push(postings);
}
};
ko.applyBindings(new viewModel());