knockout.js是我最近开始使用的一个javascript小类库. 它全部运用javascript编写, 用途是使前端用户界面(UI)的创建更为简单易读.它具有轻便灵巧(压缩前也只有29kb)的特点, 而且可以和其他流行的javascript类库(例如jquery)很好的结合运用.默认的模版语言是jquery.tmpl.
简介
我们将要学习制作一个通讯录,这个通讯录可以显示人名,地址,图片等等. 使用者可以轻松的添加新联系人,或者编辑删除已有联系人.我们将要使用knockout作为数据和ui的中间层,以此简化ui的创建过程.
一.开始上路
knockout使用View-model-viewModel构架. 以通讯录为例,界面部分称为view, 数据部分称为model, viewModel则是接受并处理用户输入,管理和协调view和model (个人理解为大脑部分).
让我们先从创建文件夹部分开始.先创建一个名为knockout的文件夹,其中包含3个子文件夹,分别为css,img,js. css文件夹里面放置stylesheet文件,img文件夹里面是我们要用的图片.js文件夹里面存放我们今天创造的script文件,除此之外还有js类库(jquery.tmpl,jquery,knockout.js,…).起初,文件夹中含有以下文件:
- jquery.tmpl.js
- jquery-1.6.2.js
- knockout-1.2.1.js
现在,在texteditor中,创造如下页面
<!DOCTYPE html>
<head>
<title>Knockout</title>
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<script src="js/jquery-1.6.2.min.js"></script>
<script src="js/jquery.tmpl.js"></script>
<script src="js/knockout-1.2.1.js"></script>
<script src="js/behavior.js"></script>
</body>
</html>
保存文件,并命名为index.html. 在knockout.js中,我们将运用html5的新特征data-*属性, 以此添加自定义的属性.
(function ($) { var model = [{ name: "John", address: "1, a road, a town, a county, a postcode", tel: "1234567890", site: "www.aurl.com", pic: "/img/john.jpg", deleteMe: function () { viewModel.people.remove(this); }
}, { name: "Jane", address: "2, a street, a city, a county, a postcode", tel: "1234567890", site: "www.aurl.com", pic: "/img/jane.jpg", deleteMe: function () { viewModel.people.remove(this); }
}, { name: "Fred", address: "3, an avenue, a village, a county, a postcode", tel: "1234567890", site: "www.aurl.com", pic: "/img/fred.jpg", deleteMe: function () { viewModel.people.remove(this); }
}, { name: "Freda", address: "4, a street, a suburb, a county, a postcode", tel: "1234567890", site: "www.aurl.com", pic: "/img/jane.jpg", deleteMe: function () { viewModel.people.remove(this); }
}], viewModel = { people: ko.observableArray(model),
}
}; ko.applyBindings(viewModel);
})(jQuery);
保存文件为behavior.js,这是一个自我调用的函数.
在model中我们创建了一个数组,数组包含有一系列people对象.people对象含有字符串(如名字,地址,url,…),还有deleteMe方法.
上面提过,viewModel引用ui的现在时,它同样是一个对象.他的第一个元素就是people数组.我们用knockout的ko.observableArray绑定modle和viewModel.
第二轮 – 创造view
我们现在已经有了model和viewmodel.我们接下来要做的将是吧viewmodel显示到页面上. 将下面的代码添加到<body>element里面,
<div id="people" data-bind="template: { name: 'personTemplate', foreach: people }">
</div>
<script id="personTemplate" type="text/x-jquery-tmpl">
<section class="person">
<img src="../img/person.png" alt="${ name }" />
<h1>${ name }</h1>
<address>${ address }</address>
<span class="tel">${ tel }</span>
<a href="http://${ site }" title="Visit site">${ site }</a>
<div class="tools">
<button data-bind="click: deleteMe">Delete</button>
</div>
</section>
</script>
我们首先加了一个空的div元素(id纯属方便css),这个div 含有特殊的属性 – data-bind. 这个属性告诉knockout这个元素要存储viewmodel的数据.当我们调用ko.applyBindings()的时候,这个databind就存储viewmodel的数据.
此外,我们用到了foreach语法进行数据遍历 ,observableArray作为数据源. 事实上我们有2个选择进行数据遍历.选择之一是用标准tmpl -> {{each}}语法. 选择之二是用knockout的syntax(如上). 用knockout的syntax更好一些,这是因为knockout会选择更新ui上面的数据,这样效率更高.
Div中其余的部分都是我们自己定义的ui,之中实用的都是tmpl的template.我们使用<section>元素作为container,值得一提的是,我们用到databind在delete按钮上面.
运行以上代码,我们将看到如下截图

很cool是吧, 但你是否觉得knockout.js 和 jquery.tmpl很相似呢?
The really cool thing is that not only is the view updated accordingly when theviewModel changes, the viewModel is also updated when the view changes. So if we click one of the delete buttons on our page, the people array will also have the corresponding person object removed from it!
我们绑定到ko.observable()的原始的数组其实并没有更新.但是正常情况下,我们需要得从ajax请求中获得数据,然后把数据填入模版中.knockout省去了中间调用ajax的过程. sweet!
第三轮 – 加入新数据
我们现在已经可以任意移除person对象了,与此同时,我们需要加入新功能,来插入新对象.更新div加入如下代码:
<a href="#" title="Add new person" data-bind="click: showForm, visible: displayButton">Add person</a>
<fieldset data-bind="visible: displayForm">
<div>
<label>Name: <input id="name" /></label>
<label>Address: <input id="address" /></label>
<label>Tel: <input id="tel" /></label>
<label>Site: <input id="site" /></label>
<div>
<div>
<label>Picture: <input id="pic" type="file" /></label>
</div>
<div>
<button data-bind="click: addPerson">Add</button>
<button data-bind="click: hideForm">Cancel</button>
</div>
</fieldset>
第一个加入的元素是<a>标签, 它来显示我们用来接受新信息的表单.原始方法中,我们会在jquery里面绑定click消息. 有了knockout之后,我们可以免去这步,创建一个新方法在viewModel, 执行我们希望的效果,knockout会自动绑定消息.
现在让我们一起看看我们需要添加哪些JavaScript 方法. 把如下代码添加到people 属性后面,
displayButton: ko.observable(true), displayForm: ko.observable(false), showForm: function () { viewModel.displayForm(true).displayButton(false);
}, hideForm: function () { viewModel.displayForm(false).displayButton(true);
}, addPerson: function () { viewModel.displayForm(false).displayButton(true).people.push({ name: $("#name").val(), address: $("#address").val(), tel: $("#tel").val(), site: $("#site").val(), pic: "", deleteMe: function () { viewModel.people.remove(this); }
});
}
第一个属性是displayButton.这个属性是一个observable属性 (意味着说他的数值会被其他对象或方法引用). 这个实体观察<a>标签的初始值为true,即意味着说,当页面载入的时候,这个<a>标签会显示在ui上面.
下一个property是displayForm. 和上面的anchor相似,但是我们副初始值为false,因为我们不想显示.
下面我们加入两个方法.一个是showForm(), 另一个是hideForm(). 这两个方法会改变displayForm和displayButton的数值.
结果如下图所示

目前为止,我们已经完成添加新用户的功能了. 新用户的数据被保存到people数组里面.
为了证明这一点,我们在代码中加入
console.log(ko.toJSON(viewModel.people));
请看下图控制台部分:

很酷是吧
原文地址: http://net.tutsplus.com/tutorials/javascript-ajax/into-the-ring-with-knockout-js/