foreach index for striping and nested use
https://groups.google.com/d/topic/knockoutjs/cJ2_2QaIJdA/discussion
by rniemeyer
HTML
<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<ul data-bind="template: { name: 'itemsTmpl', foreach: items }, stripe: items, evenClass: 'light', oddClass: 'dark'"></ul>
<button data-bind="click: addItem">Add</button>
<hr/>
<ul data-bind="template: { name: 'itemsTmpl', foreach: items }, stripe2: {watch: items, even: 'light', odd: 'dark' }"></ul>
<button data-bind="click: addItem">Add</button>
<hr/>
<ul data-bind="templateWithStripe: { name: 'itemsTmpl', foreach: items, even: 'light', odd: 'dark' }"></ul>
<button data-bind="click: addItem">Add</button>
<hr/>
<script id="itemsTmpl" type="text/html">
<li>
<span data-bind="text: id"></span>
<button data-bind="click: function() { viewModel.removeItem($data) }">Delete</button>
{{now}}
</li>
</script>
CSS
.light { background-color: #ddd; }
.dark { background-color: #bbb; }
JavaScript
var viewModel = {
items: ko.observableArray([{
id: 1},
{
id: 2},
{
id: 3},
{
id: 4}]),
addItem: function() {
this.items.push({
id: ++this.counter
});
},
removeItem: function(item) {
this.items.remove(item);
}
};
viewModel.counter = viewModel.items().length;
//separate options in binding
ko.bindingHandlers.stripe = {
update: function(element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()); //creates the dependency
var allBindings = allBindingsAccessor();
var even = allBindings.evenClass;
var odd = allBindings.oddClass;
//update odd rows
$(element).children(":nth-child(odd)").addClass(odd).removeClass(even);
//update even rows
$(element).children(":nth-child(even)").addClass(even).removeClass(odd);;
}
}
//or pass an object to the binding
ko.bindingHandlers.stripe2 = {
update: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor());
var watch = ko.utils.unwrapObservable(options.watch); //creates the dependency
//update odd rows
$(element).children(":nth-child(odd)").addClass(options.odd).removeClass(options.even);
//update even rows
$(element).children(":nth-child(even)").addClass(options.even).removeClass(options.odd);
}
}
//or wrap the template binding (assumes use of foreach)
ko.bindingHandlers.templateWithStripe = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
//call real template binding's update
ko.bindingHandlers.template.update(element, valueAccessor, allBindingsAccessor, viewModel);
var options = valueAccessor();
var value = ko.utils.unwrapObservable(options.foreach); //creates the dependency
//update odd rows
...