Knockout.js应用

Knockout是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化。

下载和安装

Github官网

MVVM 和 View Model

Model-View-View Model (MVVM) 是一种创建用户界面的设计模式。 描述的是如何将复杂的UI用户界面分成3个部分:

  • model: 你程序里存储的数据。这个数据包括对象和业务操作(例如:银子账户可以完成转账功能), 并且独立于任何UI。使用KO的时候,通常说是向服务器调用Ajax读写这个存储的模型数据。
  • view model: 在UI上,纯code描述的数据以及操作。例如,如果你实现列表编辑,你的view model应该是一个包含列表项items的对象和暴露的add/remove列表项(item)的操作方法。

    注意这不是UI本身:它不包含任何按钮的概念或者显示风格。它也不是持续数据模型 – 包含用户正在使用的未保存数据。使用KO的时候,你的view models是不包含任何HTML知识的纯JavaScript 对象。保持view model抽象可以保持简单,以便你能管理更复杂的行为。

  • view: 一个可见的,交互式的,表示view model状态的UI。 从view model显示数据,发送命令到view model(例如:当用户click按钮的时候) ,任何view model状态改变的时候更新。

简单的介绍一下

其实简而言之一句话,MVVM就是用来实现数据的双向绑定,让你在开发的时候只更改数据而不用耗费精力处理显示的内容。
例如我们现在要在页面上做一个菜单的下拉列表,数据内容如下:

1
2
3
4
5
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 }
];

如果想让这3个选项显示到页面上,我们可以绑定一个下拉菜单(例如:select元素)到这个数据上。例如:

1
2
3
<h3>Meal upgrades</h3>
<p>Make your flight more bearable by selecting a meal to match your social and economic status.</p>
Chosen meal: <select data-bind="options: availableMeals,optionsText: 'mealName'"></select>

启用Knockout并使你的绑定生效,在availableMeals变量声明之后添加如下代码:

1
2
3
4
5
6
var viewModel = {
/* we'll populate this in a moment */
};
ko.applyBindings(viewModel); // Makes Knockout get to work
// 注意:ko. applyBindings需要在上述HTML之后应用才有效

下一步,声明一个简单的data model来描述旅客已经选择的套餐,添加一个属性到当前的view model上:

1
2
3
var viewModel = {
chosenMeal: ko.observable(availableMeals[0])
};

ko.observable是什么?它是KO里的一个基础概念。UI可以监控(observe)它的值并且回应它的变化。这里我们设置chosenMeal是UI可以监控已经选择的套餐,并初始化它,使用availableMeal里的第一个值作为它的默认值(例如:Standard)。

让我们将chosenMeal 关联到下拉菜单上,仅仅是更新select的data-bind属性,告诉它让select元素的值读取/写入chosenMeal这个模型属性:

1
2
3
Chosen meal: <select data-bind="options: availableMeals,
optionsText: 'mealName',
value: chosenMeal"></select>

理论上说,我们现在可以读/写chosenMeal 属性了,但是我们不知道它的作用。让我们来显示已选择套餐的描述和价格:

1
2
3
4
5
<p>
You've chosen:
<b data-bind="text: chosenMeal().description"></b>
(price: <span data-bind='text: chosenMeal().extraCost'></span>)
</p>

好啦,一个最简单的数据双向绑定完成啦。