knockout template nested
example of knockout using nested templates
by homer2
HTML
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.0.js"></script>
<table border="1">
<tr><td class="right"><label for="edit">Edit</label></td><td class="left"><input id="edit" type="radio" value="editTmpl" data-bind="checked: mode" /></td></tr>
<tr><td class="right"><label for="readOnly">Read Only</label></td><td class="left"><input id="readOnly" type="radio" value="readOnlyTmpl" data-bind="checked: mode" /></td></tr>
</table>
<div data-bind="foreach: companies"> <span data-bind="text:name"></span>
<table data-bind="foreach: orders"
border="1">
<thead>
<tr>
<th>CompanyId</th>
<th>OrderId</th>
<th>LineItemId</th>
<th>Product</th>
<th>Quantity</th>
</tr>
</thead>
<tbody data-bind="foreach: lineItems">
<tr>
<td data-bind="text: $parents[1].id"></td>
<td data-bind="text: $parents[0].id"></td>
<td data-bind="text:id"></td>
<td data-bind="template: { name: $root.mode(), data: {field: product} }"></td>
<td data-bind="template: { name: $root.mode(), data: {field: quantity} }"></td>
</tr>
</tbody>
</table>
</div>
<br/>
<div data-bind="foreach: companies"> <span data-bind="text:name"></span>
<table data-bind="foreach: orders"
border="1">
<thead>
<tr>
<th>CompanyId</th>
<th>OrderId</th>
<th>LineItemId</th>
<th>Product</th>
<th>Quantity</th>
</tr>
</thead>
<tbody data-bind="template: {name: 'lineItemRow', foreach: lineItems}">
</tbody>
</table>
</div>
<script type="text/html" id="lineItemRowTest">
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
</script>
<script type="text/html" id="lineItemRow">
<tr>
<td...
CSS
input {
width: 60px;
}
JavaScript
function LineItem(id, orderId, product, quantity) {
var self = this;
self.id = id;
self.orderId = orderId;
self.product = ko.observable(product);
self.quantity = ko.observable(quantity);
}
function Order(id, companyId) {
var self = this;
self.id = id;
self.companyId = companyId;
self.lineItems = ko.observableArray();
self.addLineItems = function (lineItems) {
if ($.isArray(lineItems)) {
ko.utils.arrayPushAll(self.lineItems(), lineItems);
self.lineItems.valueHasMutated();
} else {
self.lineItems.push(lineItems);
}
};
self.removeListItem = function (lineItem) {
self.lineItems.remove(lineItem);
};
}
function Company(id, name) {
var self = this;
self.id = id;
self.name = ko.observable(name);
self.orders = ko.observableArray();
self.addOrders = function (orders) {
if ($.isArray(orders)) {
ko.utils.arrayPushAll(self.orders(), orders);
self.orders.valueHasMutated();
} else {
self.orders.push(orders);
}
};
self.removeOrder = function (order) {
self.orders.remove(order);
};
}
function MyViewModel() {
var self = this;
self.mode = ko.observable("editTmpl");
self.companies = ko.observableArray();
self.addCompanies = function (companies) {
if ($.isArray(companies)) {
ko.utils.arrayPushAll(self.companies(), companies);
self.companies.valueHasMutated();
} else {
self.companies.push(companies);
}
};
self.removeCompany = function (company) {
self.companies.remove(company);
};
}
var vm = new MyViewModel();
vm.addCompanies(new Company(1, "Firsties"));
vm.companies()[0].addOrders(new Order(1, 1));
vm.companies()[0].orders()[0].addLineItems(new LineItem(1, 1, "milk", 8));
vm.companies()[0].orders()[0].addLineItems(new LineItem(2, 1, "pizza",...