1. 四大关键理念:
A. DeclarativeBindings(声明式绑定)
Easily associate DOM elements with model data using a concise, readable syntax
使用简单易读的语法方便地将模型数据与DOM元素绑定在一起
B. AutomaticUIRefresh(页面自动刷新)
When your data model's state changes, your UI updates automatically
C. DependencyTracking(依赖追踪)
Implicitly set up chains of relationships between model data, to transform and combine it
使用可观察对象在模型数据之间设立隐性关系链,用于数据转换和绑定。
D. Templating(模板)
Quickly generate sophisticated, nested UIs as a function of your model data
内置模板引擎、为你的模型数据快速编写复杂的 UI 展现
2. 声明式绑定
声明式绑定即它的声明的同时也进行了绑定(自己的理解)。
3. applyBindings
Activates knockout.js -ko.applyBindings(new AppViewModel());
激活knockout.js(即激活data-bind属性)
4. observables - these are properties that automatically will issue notifications whenever their(View Models) value changes
双向绑定,当ViewModel中的值发生变化时,Dom元素的值也会相应地发生变化,反之亦然。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<script type="text/javascript" src="knockout-3.4.0.js"></script>
<script type="text/javascript">
window.onload = function ()
{
ko.applyBindings(new AppViewModel());
} function AppViewModel()
{
this.firstName = ko.observable("Hello ");
this.lastName = ko.observable("World!");
this.fullName = ko.computed(function () {
return this.firstName() + " " + this.lastName();
},this);
this.capitalizeLastName = function ()
{
var currentVal = this.lastName();
this.lastName(currentVal.toUpperCase());
}
} </script>
</head>
<body>
<P>First Name:<input data-bind="value: firstName" /></P>
<P>Last Name:<input data-bind="value: lastName" /></P>
<p>FullName:<input data-bind="value: fullName" /></p>
<button data-bind="click: capitalizeLastName">Go Caps</button>
</body>
</html>
5. knockout例子(座位预订)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<script type="text/javascript" src="knockout-3.4.0.js"></script>
<script type="text/javascript">
function SeatReservation(name,initialMeal)
{
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function () {
var price = self.meal().price;
return price ? "$" + price.toFixed(2) : "None";
});
} function ReservationsViewModel()
{
var self = this;
self.availableMeals = [
{ mealName: "Standard(Sandwich)", price: 0 },
{ mealName: "Premium:(lobster)", price: 34.95 },
{ mealName:"Ultimate(whole zebra)",price:290}
];
self.seats = ko.observableArray([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0])
]); self.addSeat = function () {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}; self.removeSeat = (function (seat) {
self.seats.remove(seat);
}); self.totalSurcharge = ko.computed(function () {
var total = 0;
for (var i = 0; i < self.seats().length; i++)
{
total += self.seats()[i].meal().price;
}
return total;
})
}
window.onload = function () {
ko.applyBindings(new ReservationsViewModel());
} </script>
</head>
<body>
<h2>Your seat reservations</h2>
<table>
<thead>
<tr>
<th>Passenger name</th>
<th>Meal</th>
<th>Surcharge</th>
</tr>
</thead>
<tbody data-bind="foreach:seats">
<tr>
<td><input data-bind="value:name"/></td>
<td><select data-bind="options:$root.availableMeals,value:meal,optionsText:'mealName'"></select></td>
<td data-bind="text:formattedPrice"></td>
<td><a href="#" data-bind="click:$root.removeSeat">Remove</a></td>
</tr>
</tbody>
</table>
<h3 data-bind="visible:totalSurcharge()>0">
Total surcharge:$<span data-bind="text:totalSurcharge().toFixed(2)"></span>
</h3>
<button data-bind="click:addSeat,enable:seats().length<10">Reserve another seat</button> </body>
</html>
6.Knockout使用<!--ko--><!--/ko-->来表示循环的开始和结束;
切记不是注释!
7. 总结分析:
问题一:在第一个例子中,在调用ko.computed()方法时,第二个参数this的作用?
答:这个和JS中的基本一致,是为了ko.computed()方法内部的使用而传入的;
问题二:在第二个例子中,什么时候用meal,什么时候用meal()?(以下为官网说法)
Notice that, because the meal property is an observable, it's important to invoke meal() as a function (to obtain
its current value) before attempting to read sub-properties. In other words, write meal().price, not meal.price.
因为meal的属性是observable,在获取该类型当前值时,必须将其作为一个函数来使用,即 meal() ,换句话说就是meal().price,而不是meal.price。