微软MVC框架功力深厚:Web开发化繁为简
- Knockout.js框架与MVVM模式
前言
Knockout神马是MVVM?初探knockout水深结语
前言:
初次尝试使用VS2012创建ASP.NET MVC4项目时,无意间发现微软的Script文件夹中增加了knockout-2.1.0.debug.js与knockout-2.1.0.js两个JS文件。第一次对这个名子有一个简单的印象。另一次机会,接触到一个商业源码,代码是C#的,使用的后台技术是ASP.NET MVC4,前端用的蔭syUI与Knockout.js,代码简洁、优雅,界面华丽,用户体验良好,功能强大。深入研究之后,我发现在自己深深的爱上这个神奇的客户端JS框架。经过尽一个月的深入研究,我基本全面深入了解了这套客户端框架,也准备录制相关视频教程把这个强大的框架与大家分享。接下来,我简单的给大家介绍一下这个框架。
Knockout
Knockout (或者Knockout.js ,KnockoutJS)是一个开源的JavaScript库,网址为 www.knockoutjs.com 。Knockout语法简洁、可读性好,能轻松实现与DOM元素的关联。一旦数据模型的状态发生改变,则立即自动刷新UI。Knockout采用Model-View-View-Model (MVVM)的设计模式来简化动态JavaScript UI。Knockout有效实现了JavaScript与UI HTML呈现的分离。有了Knockout,在写JavaScript时,就不需要在页面中引用UI元素或DOM。
Knockout设计目标是把任何JavaScript对象当成View Model来使用。只要View Model的属性具有可监听性,就可以使用Knockout将其与UI绑定。一旦属性值发生变化时,UI会被自动刷新。
神马是MVVM
借用我们百科一张美图,所谓MVVM就是model-view-viewmodel模型。
他是微软带来的一项新的技术体验,最先用于WPF,最后发现其模式对前端开发尤其比较合适,所以便在前端流行起来了。
MVVM是对MVC的一个改进,用以适应当代Web开发。
model为数据或者业务逻辑,完全与UI无关,它存储了状态并对问题领域做出处理,model可以写在代码里面或者用json表示、或者数据表中,反正他就是数据啦。
view表示可见元素,按钮、标签、图片等,我们可能会对各个标签绑定事件,但是我们知道这其实是原来controller该做的事情。
简单例子中view被直接绑定到model,model的一些部分只是简单单向绑定显示在view中。
初探knockout水深
讲了这么多理论,朋友们未必能理解到Knockout框架的强大之处,下面就通过几个具体的实例让大家快速上手。
-
<html xmlns=\"http://www.w3.org/1999/xhtml\">
-
<head>
-
<title></title>
-
<script src=\"js/jquery-1.7.1.js\" type=\"text/javascript\"></script>
-
<script src=\"js/knockout-2.2.0.js\" type=\"text/javascript\"></script>
-
<script type=\"text/javascript\">
-
var piliPerson = [
-
{ name: \'叶小钗\', desc: \'刀狂剑痴\', weapon: \'刀剑\' },
-
{ name: \'素还真\', desc: \'清香白莲\', weapon: \'剑\' },
-
{ name: \'一页书\', desc: \'百世经纶\', weapon: \'掌\' }
-
];
-
$(document).ready(function () {
-
var viewModel = {};
-
ko.applyBindings(viewModel);
-
});
-
</script>
-
</head>
-
<body>
-
<select data-bind=\"options: piliPerson, optionsText: \'name\'\">
-
</select>
-
</body>
-
</html>
效果:
我们再拓宽:
-
<html xmlns=\"http://www.w3.org/1999/xhtml\">
-
<head>
-
<title></title>
-
<script src=\"js/jquery-1.7.1.js\" type=\"text/javascript\"></script>
-
<script src=\"js/knockout-2.2.0.js\" type=\"text/javascript\"></script>
-
<script type=\"text/javascript\">
-
var piliPerson = [
-
{ name: \'叶小钗\', desc: \'刀狂剑痴\', weapon: \'刀剑\', key: \'yxc\' },
-
{ name: \'素还真\', desc: \'清香白莲\', weapon: \'剑\', key: \'shz\' },
-
{ name: \'一页书\', desc: \'百世经纶\', weapon: \'掌\', key: \'yys\' }
-
];
-
$(document).ready(function () {
-
var viewModel = {
-
//observable是一个KO的基础概念,UI可健康(observe)他的值,并且回应他的变化
-
//这里相当于设置了其选择项,当前选择的素还真
-
choseObj: ko.observable(piliPerson[1])
-
};
-
ko.applyBindings(viewModel);
-
});
-
</script>
-
</head>
-
<body>
-
<select data-bind=\"options: piliPerson, optionsText: \'name\', value: choseObj\">
-
<option ></option>
-
</select>
-
选择了:<span data-bind=\"text: choseObj().name\"></span>
-
</body>
-
</html>
效果:
比较神奇的是,我们可以在标签里面使用函数了,和最初的.net越来越靠近了:
-
function formatStr(name) {
-
return name ? \'霹雳人物:\' + name : \'\';
-
}
效果:
以上算是一个初体验,下面我们再来给大家举一个更深入一点的示例:
接下来的这个示例主要是关于KO里结合运用列表(List)和集合(Collection)。第一步:首先通过HTML建立一个table。
-
<h2>购买清单</h2>
-
<h3 data-bind=\"visible: totalSurcharge() > 0\">
-
总价: [ wind_phpcode_4 ]lt;span data-bind=\"text: totalSurcharge().toFixed(2)\"></span>
-
</h3>
-
<button data-bind=\"click: addSeat\">添加</button>
-
<table>
-
<thead>
-
<tr>
-
<th>客户名称</th><th>餐单</th><th>价格</th><th></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\">删除</a></td>
-
</tr>
-
</tbody>
-
</table>
这里的HTML标签中通过data-bind绑定了很多Ko的事件。因为太懒,直接把最终的HTML贴出来了,JS还是一步一步来吧。这里先不解释,在接下来的步骤中再一一揭晓。
第二步:JS代码
-
// Class to represent a row in the seat reservations grid
-
function SeatReservation(name, initialMeal) {
-
var self = this;
-
self.name = name;
-
self.meal = ko.observable(initialMeal);
-
}
-
// Overall viewmodel for this screen, along with initial state
-
function ReservationsViewModel() {
-
var self = this;
-
// Non-editable catalog data - would come from the server
-
self.availableMeals = [
-
{ mealName: \"Standard (sandwich)\", price: 0 },
-
{ mealName: \"Premium (lobster)\", price: 34.95 },
-
{ mealName: \"Ultimate (whole zebra)\", price: 290 }
-
];
-
// Editable data
-
self.seats = ko.observableArray([
-
new SeatReservation(\"G7\", self.availableMeals[0]),
-
new SeatReservation(\"Zhipeng\", self.availableMeals[2])
-
]);
-
}
-
ko.applyBindings(new ReservationsViewModel())
这段代码中,SeatReservation作为一个构造函数,用于存储简单的餐单信息,如价格,商户。ko.observable(initialMeal)这里是Knockoutjs的动态绑定数据方法,能双向沟通数据。详见Ko的文档。ReservationsViewModel作为一个ViewMode,包含了一个availableMeals数组,一个名为seats的属性,使用了ko.observableArray先初始化了两个值,并能在数组项添加删除的时候自动更新UI。然后回到html结构中,看到tbody中的foreach:seats和td中的data-bind应该懂了吧。现在的js代码只是实现了数据的静态展示,现在要加上一个addSeats方法往表格添加和删除行,并且能通过下拉框更改餐单。
-
function ReservationsViewModel() {
-
// ... leave all the rest unchanged ...
-
// Operations
-
self.addSeat = function() {
-
self.seats.push(new SeatReservation(\"G7Note\", self.availableMeals[2]));
-
}
-
self.removeSeat = function(seat) {
-
self.seats.remove(seat)
-
}
-
}
很简单,就这样便可以实现添加功能,及删除功能。结合以上HTML代码中data-bind="click: $root.removeSeat"也不难理解。最后的功能便是添加总额显示,以及当总额小于零时不显示。
-
function ReservationsViewModel() {
-
// ... leave all the rest unchanged ...
-
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;
-
});
-
}
这里使用了ko.computed当下拉框选择项改变时,动态更新总价UI。大概的思路到此边结束了。所用到的Ko的API也 是很简单易懂,但确能轻松地操作UI层的DOM,也能方便地更新ViewModel层的DATA。相比起Backbone.js的重型杀伤武器,Ko在这 里扮演的角色更像瑞士******,小巧却犀利
结论
经过今天的学习,虽然大家没能完全了解MVVM是什么,但是也有所增长,更是发现了ko这个神器,相信一定和我一样,让你眼前一亮。
接下来,把自己最近一段时间的研究成果与及准备录制的视频课程课件在这里向大家展示一下:
课程思维导图:

另把最近已经录制好的内容和大家分享下:

另把最近已经录制好的内容和大家分享下:
具体见网盘下载地址!
具体的课程预计讲数在:20+,预计课程录制结束时间在2014年6月份,有需要了解课程详情的可咨询官网客服。
因为时间有限,对KO的研究不久,讲解有不到位之处,欢迎大家抛砖。
网盘下载地址:
链接: http://pan.baidu.com/s/18IX0i
密码查看地址:
http://bbs.ibeifeng.com/read-htm-tid-65558.html
推荐:
asp.net视频教程:风舞烟ASP.NET软件工程师IT高端培训(BF-TECH3.0)-10年IT从业经验结晶
http://www.ibeifeng.com/netcourse.html
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29511780/viewspace-1192030/
,如需转载,请注明出处,否则将追究法律责任。