JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>
<div data-bind="template: {afterRender: hide}">
<table data-bind="html: html">
</table>
</div>
<div id="spinner" style="display: none">Loading...</div>
<button onclick="go()">Go!</button>
CSS
#spinner {
position: absolute;
top: 20px;
left: 20px;
background-color: white;
border: 1px solid green;
}
.stripe {
background-color: red;
}
JavaScript
// Use a non-observable array to build the 5000 items
plain_items = [];
// Build 5000 items, as a performance challenge!
for (var i = 0; i <= 5000; i++) {
plain_items.push("Item " + i)
}
// Put the items in a VM
list = function() {
this.items = ko.observableArray()
// This HTML will be displayed in a single DOM manipulation via the html binding,
// which is faster than inserting each row one by one into the DOM.
this.html = ko.computed(function() {
var html = "", i = 0, item
for (i = 0; i < this.items().length; i++) {
var item = this.items()[i];
html = html + "<tr><td>" + item + "</td><td><button onclick=\"retrieve(" + i + ", 'delete')\">delete</button></td></tr>"
}
return html;
}, this)
}
vm = new list()
// Trigger the rendering from a button click
go = function() {
// Show the spinner immediately...
$("#spinner").show();
// ... by using a timeout.
window.setTimeout(function() {
ko.applyBindings(vm)
vm.items(plain_items)
}, 1)
}
// Hide the spinner by applying this function to a template: {afterRender: ...} binding
hide = function() {
$("#spinner").hide()
}
// Retrieve the item from the index
retrieve = function(i, action) {
var item = vm.items()[i]
if (action == "delete") vm.items.remove(item)
// You could put other actions here...
// else if (action == "edit") vm.edit(item)
}