這個例子,對view model沒有什麼特殊的展現,只是展現如何綁定到各類元素上(例如,select, radio button等)。html
代碼: Viewapp
<div class="readout">
<h3>
What's in the model?</h3>
<table>
<tr>
<td class="label">
Text value:
</td>
<td data-bind="text: stringValue">
</td>
</tr>
<tr>
<td class="label">
Password:
</td>
<td data-bind="text: passwordValue">
</td>
</tr>
<tr>
<td class="label">
Bool value:
</td>
<td data-bind='text: booleanValue() ? "True" : "False"'>
</td>
</tr>
<tr>
<td class="label">
Selected option:
</td>
<td data-bind="text: selectedOptionValue">
</td>
</tr>
<tr>
<td class="label">
Multi-selected options:
</td>
<td data-bind="text: multipleSelectedOptionValues">
</td>
</tr>
<tr>
<td class="label">
Radio button selection:
</td>
<td data-bind="text: radioSelectedOptionValue">
</td>
</tr>
</table>
</div>
<h3>
HTML controls</h3>
<table>
<tr>
<td class="label">
Text value (updates on change):
</td>
<td>
<input data-bind="value: stringValue"/>
</td>
</tr>
<tr>
<td class="label">
Text value (updates on keystroke):
</td>
<td>
<input data-bind='value: stringValue, valueUpdate: "afterkeydown"' />
</td>
</tr>
<tr>
<td class="label">
Text value (multi-line):
</td>
<td>
<textarea data-bind="value: stringValue"> </textarea>
</td>
</tr>
<tr>
<td class="label">
Password:
</td>
<td>
<input type="password" data-bind="value: passwordValue"/>
</td>
</tr>
<tr>
<td class="label">
Checkbox:
</td>
<td>
<input type="checkbox" data-bind="checked: booleanValue"/>
</td>
</tr>
<tr>
<td class="label">
Drop-down list:
</td>
<td>
<select data-bind="options: optionValues, value: selectedOptionValue">
</select>
</td>
</tr>
<tr>
<td class="label">
Multi-select drop-down list:
</td>
<td>
<select multiple="multiple" data-bind="options: optionValues, selectedOptions: multipleSelectedOptionValues">
</select>
</td>
</tr>
<tr>
<td class="label">
Radio buttons:
</td>
<td>
<label>
<input type="radio" value="Alpha" data-bind="checked: radioSelectedOptionValue"/>Alpha</label>
<label>
<input type="radio" value="Beta" data-bind="checked: radioSelectedOptionValue"/>Beta</label>
<label>
<input type="radio" value="Gamma" data-bind="checked: radioSelectedOptionValue"/>Gamma</label>
</td>
</tr>
</table>
代碼: View modelide
var viewModel = {
stringValue: ko.observable("Hello"),
passwordValue: ko.observable("mypass"),
booleanValue: ko.observable(true),
optionValues: ["Alpha", "Beta", "Gamma"],
selectedOptionValue: ko.observable("Gamma"),
multipleSelectedOptionValues: ko.observable(["Alpha"]),
radioSelectedOptionValue: ko.observable("Beta")
};
ko.applyBindings(viewModel);
這個例子展現的render模板,以及在模板內部如何使用data binding屬性的。函數
Template很容易嵌套,當任何依賴數據改變的時候,Knockout會自動從新render模板。參考演示(啓用‘Show render times’),Knockout知道只須要從新render改變的那些數據所綁定的最近的模板。post
代碼: View動畫
<div data-bind='template: "peopleTemplate"'>
</div>
<label>
<input type="checkbox" data-bind="checked: showRenderTimes"/>
Show render times</label>
<script type="text/html" id="peopleTemplate">
<h2>People</h2>
<ul>
{{each people}}
<li>
<div>
${ name } has <span data-bind="text: children().length"> </span> children:
<a href="#" data-bind="click: addChild ">Add child</a>
<span class="renderTime" data-bind="visible: showRenderTimes">
(person rendered at <span data-bind="text: new Date().getSeconds()"></span>)
</span>
</div>
<div data-bind='template: { name: "childrenTemplate", data: children }'></div>
</li>
{{/each}}
</ul>
</script>
<script type="text/html" id="childrenTemplate">
<ul>
{{each $data}}
<li>
${ this }
<span class="renderTime" data-bind="visible: viewModel.showRenderTimes">
(child rendered at <span data-bind="text: new Date().getSeconds()"></span>)
</span>
</li>
{{/each}}
</ul>
</script>
代碼: View modelthis
// Define a "person" class that tracks its own name and children, and has a method to add a new child
var person = function (name, children) {
this.name = name;
this.children = ko.observableArray(children);
this.addChild = function () {
this.children.push("New child");
} .bind(this);
}
// The view model is an abstract description of the state of the UI, but without any knowledge of the UI technology (HTML)
var viewModel = {
people: [
new person("Annabelle", ["Arnie", "Anders", "Apple"]),
new person("Bertie", ["Boutros-Boutros", "Brianna", "Barbie", "Bee-bop"]),
new person("Charles", ["Cayenne", "Cleopatra"])
],
showRenderTimes: ko.observable(false)
};
ko.applyBindings(viewModel);
data-bind="..."綁定(像text, visible, 和click不是固定死的) - 你能夠很容易自定義本身的綁定。若是你的自定義綁定僅僅是添加事件或者更新DOM元素的屬性,那幾行就能夠實現。不過,你依然能夠自定義能夠重用的綁定(或插件),就行本例的simpleGrid綁定。url
若是一個插件須要本身標準的view model(例如本例的ko.simpleGrid.viewModel ),它提供既提供了該如何配置插件實例(分頁大小,列聲明)工做,也提供了view model上的屬性是不是observable 的(例如currentpage索引)。也能夠擴展代碼讓這些屬性很容易地改變,而且讓UI自動更新。例如,「Jump to first page」按鈕的工做原理。spa
查看HTML源代碼能夠看到很是容易使用這個simple grid插件。simpleGrid源碼地址是:http://knockoutjs.com/examples/resources/knockout.simpleGrid.js插件
代碼: View
<div data-bind="simpleGrid: gridViewModel"> </div>
<button data-bind='click: function() { items.push({ name: "New item", sales: 0, price: 100 }) }'>
Add item
</button>
<button data-bind="click: sortByName">
Sort by name
</button>
<button data-bind="click: function() { gridViewModel.currentPageIndex(0) }">
Jump to first page
</button>
代碼: View model
var myModel = {
items: ko.observableArray([
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
]),
sortByName: function () {
this.items.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
}
};
myModel.gridViewModel = new ko.simpleGrid.viewModel({
data: myModel.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: 4
});
ko.applyBindings(myModel);
該例子展現了2種方式實現動畫過渡效果:
當使用template/foreach綁定的時候,你能夠使用afterAdd和beforeRemove回調函數,他們能夠讓你寫代碼真實操做添加和刪除元素,這樣你就能夠使用像jQuery的 slideUp/slideDown()這樣的動畫效果。在planet types之間切換或添加新的planet能夠看到效果。
經過observable 類型的值,咱們不難定義本身的Knockout綁定,查看HTML源代碼能夠看到一個自定義綁定fadeVisible,無論何時它改變了, jQuery就會在相關的元素上執行fadeIn/fadeOut動畫效果。點擊「advanced options」 checkbox 能夠看到效果。
代碼: View
<h2>Planets</h2>
<p>
<label>
<input type="checkbox" data-bind="checked: displayAdvancedOptions"/>
Display advanced options
</label>
</p>
<p data-bind="fadeVisible: displayAdvancedOptions">
Show:
<label><input type="radio" value="all" data-bind="checked: typeToShow"/>All</label>
<label><input type="radio" value="rock" data-bind="checked: typeToShow"/>Rocky planets</label>
<label><input type="radio" value="gasgiant" data-bind="checked: typeToShow"/>Gas giants</label>
</p>
<div data-bind='template: { name: "planetsTemplate",
foreach: planetsToShow,
beforeRemove: function(elem) { $(elem).slideUp(function() { $(elem).remove(); }) },
afterAdd: function(elem) { $(elem).hide().slideDown() } }'>
</div>
<script type="text/html" id="planetsTemplate">
<div class="planet ${ type }">${ name }</div>
</script>
<p data-bind="fadeVisible: displayAdvancedOptions">
<button data-bind='click: function() { addPlanet("rock") }'>
Add rocky planet</button>
<button data-bind='click: function() { addPlanet("gasgiant") }'>
Add gas giant</button>
</p>
代碼: View model
var viewModel = {
planets: ko.observableArray([
{ name: "Mercury", type: "rock" },
{ name: "Venus", type: "rock" },
{ name: "Earth", type: "rock" },
{ name: "Mars", type: "rock" },
{ name: "Jupiter", type: "gasgiant" },
{ name: "Saturn", type: "gasgiant" },
{ name: "Uranus", type: "gasgiant" },
{ name: "Neptune", type: "gasgiant" },
{ name: "Pluto", type: "rock" }
]),
typeToShow: ko.observable("all"),
displayAdvancedOptions: ko.observable(false),
addPlanet: function (type) { this.planets.push({ name: "New planet", type: type }); }
};
viewModel.planetsToShow = ko.dependentObservable(function () {
// Represents a filtered list of planets
// i.e., only those matching the "typeToShow" condition
var desiredType = this.typeToShow();
if (desiredType == "all")
return this.planets();
return ko.utils.arrayFilter(this.planets(), function (planet) {
return planet.type == desiredType;
});
} .bind(viewModel));
// Here's a custom Knockout binding that makes elements shown/hidden via jQuery's fadeIn()/fadeOut() methods
// Could be stored in a separate utility library
ko.bindingHandlers.fadeVisible = {
init: function (element, valueAccessor) {
// Initially set the element to be instantly visible/hidden depending on the value
var value = valueAccessor();
$(element).toggle(ko.utils.unwrapObservable(value));
// Use "unwrapObservable" so we can handle values that may or may not be observable
},
update: function (element, valueAccessor) {
// Whenever the value subsequently changes, slowly fade the element in or out
var value = valueAccessor(); ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut(); }};ko.applyBindings(viewModel);