根据汤姆大叔博客总结-笔记:
=============
<script type="text/javascript">
$(function () {
var ViewModel = function (first, last) {
this.firstName = ko.observable(first);
this.lastName = ko.observable(last);
this.fullName = ko.pureComputed(function () {
// Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
return this.firstName() + " " + this.lastName();
}, this);
};
ko.applyBindings(new ViewModel("Planet", "Earth"));
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>First name:
<input data-bind="value: firstName" /></p>
<p>Last name:
<input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"></span>!</h2>
</div>
</form>
</body>
==============
<script type="text/javascript">
$(function () {
var availableMeals = [
{ mealName: 'Standard', description: 'Dry crusts of bread', extraCost: 0 },
{ mealName: 'Premium', description: 'Fresh bread with cheese', extraCost: 9.95 },
{ mealName: 'Deluxe', description: 'Caviar and vintage Dr Pepper', extraCost: 18.50 }
];
//
var viewModel = {
ava:availableMeals,
};
ko.applyBindings(viewModel);
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
Chosen meal: <select data-bind="options: ava,
optionsText: 'description'"></select>
</div>
</form>
==================
<script type="text/javascript">
var aa = [
{ name: 'Bert' },
{ name: 'Charles' },
{ name: 'Denise' }
];
var bb = [
{ name: '1111' },
{ name: '2222' },
{ name: '33333' }
];
function AppViewModel() {
var self = this;
self.people = ko.observableArray(aa);
self.addPerson = function () {
self.people.removeAll();
self.people.push({ name: "New at " + new Date() });
};
self.removePerson = function () {
self.people.remove(this);
}
}
var aaa = new AppViewModel();
function test() {
//aaa.people.removeAll();
aa.push({ name: '33333' });
//aaa.addPerson();
}
$(function () {
ko.applyBindings(aaa);
});
</script>
</head>
<body>
<%-- <input type="button" value="测试" id="cc" />
<table>
<tbody data-bind="foreach: ava(), visible: ava().length > 0">
<tr>
<td class="centerdata" data-bind="text: mealName"></td>
<td class="centerdata" data-bind="text: description"></td>
</tr>
</tbody>
</table>--%>
<h4>People</h4>
<ul data-bind="foreach: people">
<li>Name at position <span data-bind="text: $index"></span>:
<span class="ttt" data-bind="text: name"></span>
<a href="#" data-bind="click: $parent.removePerson">Remove</a>
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
<button onclick="test()">手动事件</button>
</body>
</html>
============================
myObservableArray.push('Some new value');// 在数组末尾添加一个新项
myObservableArray.pop();// 删除数组最后一个项并返回该项
myObservableArray.unshift('Some new value');// 在数组头部添加一个项
myObservableArray.shift();// 删除数组头部第一项并返回该项
myObservableArray.reverse();// 翻转整个数组的顺序
myObservableArray.sort();// 给数组排序
=============还可以调用方法:
(price: <span data-bind='text: formatPrice(chosenMeal().extraCost)'></span>)
======赋值取值案例:
<script type="text/javascript">
var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable(123)
};
$(function () {
var aa=ko.applyBindings(myViewModel);
$("#Text1").click(function () {
myViewModel.personName("郭泽峰");
// alert(myViewModel.personName());
});
})
</script>
</head>
<body>
<input id="input" type="text" data-bind="value:personName"/>
<input id="Text1" type="button" value="测试"/>
</body>
========================级联样式属性:
<script type="text/javascript">
var viewModel = {
firstName: ko.observable('Bob'),
lastName: ko.observable('Smith')
};
viewModel.fullName = ko.dependentObservable(function () {
return this.firstName() + " " + this.lastName();
}, viewModel);
$(function () {
ko.applyBindings(viewModel);
$("#Text1").click(function () {
viewModel.firstName("郭泽峰");
// alert(myViewModel.personName());
});
})
</script>
</head>
<body>
<input id="input" type="text" data-bind="value:fullName"/>
<input id="Text1" type="button" value="测试"/>
</body>
=========拆分案例:
var viewModel = {
firstName: ko.observable("Planet"),
lastName: ko.observable("Earth")
};
viewModel.fullName = ko.dependentObservable({
read: function () {
return this.firstName() + " " + this.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) { // Ignore values with no space character
this.firstName(value.substring(0, lastSpacePos)); // Update "firstName"
this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
}
},
owner: viewModel
});
这个例子里,写操作的callback接受写入的值,把值分离出来,分别写入到“firstName”和“lastName”上。 你可以像普通情况一样将这个view model绑定到DOM元素上,如下:
<p>First name: <span data-bind="text: firstName"></span></p>
<p>Last name: <span data-bind="text: lastName"></span></p>
<h2>Hello, <input data-bind="value: fullName"/>!</h2>
==============显示隐藏的例子:
<div data-bind="visible: shouldShowMessage">
You will see this message only when "shouldShowMessage" holds a true value.
</div>
<script type="text/javascript">
var viewModel = {
shouldShowMessage: ko.observable(true) // Message initially visible
};
viewModel.shouldShowMessage(false); // ... now it's hidden
viewModel.shouldShowMessage(true); // ... now it's visible again
</script>
=====
ko.applyBindings(myViewModel, document.getElementById('someElementId'))。它的现在是只有作为someElementId 的元素和子元素才能激活KO功能。
=====依赖:
viewModel.fullName = ko.dependentObservable(function () {
return this.firstName() + " " + this.lastName();
}, viewModel);
并且绑定到UI的元素上,例如:
The name is <span data-bind="text: fullName"></span>
===========分解:
var viewModel = {
firstName: ko.observable("Planet"),
lastName: ko.observable("Earth")
};
viewModel.fullName = ko.dependentObservable({
read: function () {
return this.firstName() + " " + this.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) { // Ignore values with no space character
this.firstName(value.substring(0, lastSpacePos)); // Update "firstName"
this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
}
},
owner: viewModel
});
<p>First name: <span data-bind="text: firstName"></span></p>
<p>Last name: <span data-bind="text: lastName"></span></p>
<h2>Hello, <input data-bind="value: fullName"/>!</h2>
=========监控输入规范,如果不规范则禁止输入:
viewModel.formattedPrice = ko.dependentObservable({
read: function () {
return "$" + this.price().toFixed(2);
},
write: function (value) {
// Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable
value = parseFloat(value.replace(/[^.d]/g, ""));
this.price(isNaN(value) ? 0 : value); // Write to underlying storage
},
owner: viewModel
});
===================输入验证:
var viewModel = {
acceptedNumericValue: ko.observable(123),
lastInputWasValid: ko.observable(true)
};
viewModel.attemptedValue = ko.dependentObservable({
read: viewModel.acceptedNumericValue,
write: function (value) {
if (isNaN(value))
this.lastInputWasValid(false);
else {
this.lastInputWasValid(true);
this.acceptedNumericValue(value); // Write to underlying storage
}
},
owner: viewModel
});
… 按照如下格式声明绑定元素:
<p>Enter a numeric value: <input data-bind="value: attemptedValue"/></p>
<div data-bind="visible: !lastInputWasValid()">That's not a number!</div>
===显示或隐藏:
visible
====
<div data-bind="visible: shouldShowMessage">
You will see this message only when "shouldShowMessage" holds a true value.
</div>
<script type="text/javascript">
var viewModel = {
shouldShowMessage: ko.observable(true) // Message initially visible
};
viewModel.shouldShowMessage(false); // ... now it's hidden
viewModel.shouldShowMessage(true); // ... now it's visible again
</script>
====绑定html标签:
<div data-bind="html: details"></div>
<script type="text/javascript">
var viewModel = {
details: ko.observable() // Initially blank
};
viewModel.details("<em>For further details, view the report <a href='report.html'>here</a>.</em>");
// HTML content appears
</script>
=====绑定css
<div data-bind="css: { profitWarning: currentProfit() < 0 }">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000)
// Positive value, so initially we don't apply the "profitWarning" class
};
viewModel.currentProfit(-50);
// Causes the "profitWarning" class to be applied
</script>
--多个class属性:
<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">
==============style:
<div data-bind="style: { color: currentProfit() < 0 ? 'red' : 'black' }">
Profit Information
</div>
如果你需要应用font-weight或者text-decoration,你不能直接使用,而是要使用style对应的JavaScript名称。
错误: { font-weight: someValue }; 正确: { fontWeight: someValue }
错误: { text-decoration: someValue }; 正确: { textDecoration: someValue }
===========
<a data-bind="attr: { href: url, title: details }">
Report
</a>
<script type="text/javascript">
var viewModel = {
url: ko.observable("year-end.html"),
details: ko.observable("Report including final year-end statistics")
};
</script>
呈现结果是该连接的href属性被设置为year-end.html, title属性被设置为Report including final year-end statistics。
这样写不对:
<div data-bind="attr: { data-something: someValue }">...</div>
要这样写:
<div data-bind="attr: { ‘data-something’: someValue }">...</div>
============click:
<div>
You've clicked <span data-bind="text: numberOfClicks"></span> times
<button data-bind="click: incrementClickCounter">Click me</button>
</div>
<script type="text/javascript">
var viewModel = {
numberOfClicks: ko.observable(0),
incrementClickCounter: function () {
var previousCount =this.numberOfClicks();
this.numberOfClicks(previousCount +1);
}
};
</script>
============匿名:
<button data-bind="click: function() { viewModel.myFunction('param1', 'param2') }">
Click me
</button>
===event:
<div>
<div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }">
Mouse over me
</div>
<div data-bind="visible: detailsEnabled">
Details
</div>
</div>
===========checked:
<input type='checkbox' data-bind="checked: hasCellphone"/>
=========enabled:
<button data-bind="enabled: parseAreaCode(viewModel.cellphoneNumber()) != '555'">
Do something
</button>
== disable
===
其它参数
valueUpdate
如果你使用valueUpdate参数,那就是意味着KO将使用自定义的事件而不是默认的离开焦点事件。下面是一些最常用的选项:
“change”(默认值) - 当失去焦点的时候更新view model的值,或者是<select> 元素被选择的时候。
“keyup” – 当用户敲完一个字符以后立即更新view model。
“keypress” – 当用户正在敲一个字符但没有释放键盘的时候就立即更新view model。不像 keyup,这个更新和keydown是一样的。
“afterkeydown” – 当用户开始输入字符的时候就更新view model。主要是捕获浏览器的keydown事件或异步handle事件。
上述这些选项,如果你想让你的view model进行实时更新,使用“afterkeydown”是最好的选择。
例子:
<p>Your value: <input data-bind="value: someValue, valueUpdate: 'afterkeydown'"/></p>
<p>You have typed: <span data-bind="text: someValue"></span></p> <!-- updates in real-time -->
<script type="text/javascript">
var viewModel = {
someValue: ko.observable("edit me")
};
</script>
=============checked:
<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam"/></p>
<script type="text/javascript">
var viewModel = {
wantsSpam: ko.observable(true) // Initially checked
};
// ... then later ...
viewModel.wantsSpam(false); // The checkbox becomes unchecked
</script>
======
Checkbox关联到数组
<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam"/></p>
<div data-bind="visible: wantsSpam">
Preferred flavors of spam:
<div><input type="checkbox" value="cherry" data-bind="checked: spamFlavors"/> Cherry</div>
<div><input type="checkbox" value="almond" data-bind="checked: spamFlavors"/> Almond</div>
<div><input type="checkbox" value="msg" data-bind="checked: spamFlavors"/> Monosodium Glutamate</div>
</div>
<script type="text/javascript">
var viewModel = {
wantsSpam: ko.observable(true),
spamFlavors: ko.observableArray(["cherry", "almond"]) // Initially checks the Cherry and Almond checkboxes
};
// ... then later ...
viewModel.spamFlavors.push("msg"); // Now additionally checks the Monosodium Glutamate checkbox
</script>
======checked:
<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam"/></p>
<div data-bind="visible: wantsSpam">
Preferred flavor of spam:
<div><input type="radio" name="flavorGroup" value="cherry" data-bind="checked: spamFlavor"/> Cherry</div>
<div><input type="radio" name="flavorGroup" value="almond" data-bind="checked: spamFlavor"/> Almond</div>
<div><input type="radio" name="flavorGroup" value="msg" data-bind="checked: spamFlavor"/> Monosodium Glutamate</div>
</div>
<script type="text/javascript">
var viewModel = {
wantsSpam: ko.observable(true),
spamFlavor: ko.observable("almond") // Initially selects only the Almond radio button
};
// ... then later ...
viewModel.spamFlavor("msg"); // Now only Monosodium Glutamate is checked
</script>
===============select
<p>Destination country: <select data-bind="options: availableCountries"></select></p>
<script type="text/javascript">
var viewModel = {
availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) // These are the initial options
};
// ... then later ...
viewModel.availableCountries.push('China'); // Adds another option
</script>
=================Multi-select list
<p>Choose some countries you'd like to visit: <select data-bind="options: availableCountries" size="5" multiple="true"></select></p>
<script type="text/javascript">
var viewModel = {
availableCountries: ko.observableArray(['France', 'Germany', 'Spain'])
};
</script>
=========
例3:Drop-down list展示的任意JavaScript对象,不仅仅是字符串
<p>
Your country:
<select data-bind="options: availableCountries,
optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"></select>
</p>
<div data-bind="visible: selectedCountry"> <!-- Appears when you select something -->
You have chosen a country with population
<span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>.
</div>
<script type="text/javascript">
// Constructor for an object with two properties
var country =function (name, population) {
this.countryName = name;
this.countryPopulation = population;
};
var viewModel = {
availableCountries: ko.observableArray([
new country("UK", 65000000),
new country("USA", 320000000),
new country("Sweden", 29000000)
]),
selectedCountry: ko.observable() // Nothing selected by default
};
</script>
============select:选中:
<p>
Choose some countries you'd like to visit:
<select data-bind="options: availableCountries, selectedOptions: chosenCountries" size="5" multiple="true"></select>
</p>
<script type="text/javascript">
var viewModel = {
availableCountries: ko.observableArray(['France', 'Germany', 'Spain']),
chosenCountries: ko.observableArray(['Germany']) // Initially, only Germany is selected
};
// ... then later ...
viewModel.chosenCountries.push('France'); // Now France is selected too
</script>
=============动态修改引擎模板:
例子
<div data-bind='template: "personTemplate"'> </div>
<script id='personTemplate' type='text/html'>
${ name } is ${ age } years old
<button data-bind='click: makeOlder'>Make older</button>
</script>
<script type='text/javascript'>
var viewModel = {
name: ko.observable('Bert'),
age: ko.observable(78),
makeOlder: function () {
this.age(this.age() +1);
}
};
ko.applyBindings(viewModel);
</script>
当引用的observable(dependent observable)数据改变的时候,Knockout会自动重新render模板。在这个例子里,每次点击button的时候都会重新render模板。
=======动态切换模板引擎:
<ul data-bind='template: { name: "personTemplate",
foreach: employees,
templateOptions: { label: "Employee:",
selectedPerson: selectedEmployee } }'> </ul>
<script id='personTemplate' type='text/html'>
<div data-bind="css: { selected: $data === $item.selectedPerson()" }">
${ $item.label } <input data-bind="value: name" />
</div>
</script>