BACKBONE.JS 简单入门范例简单入门范例
Backbone简单、灵活,无论是富JS应用还是企业网站都用得上,相比React针对View和单向数据流的设计,Backbone更能体现MVC的思路,所以针对它写一篇入门范例,需要的朋
友可以参考下
11年刚开始用前端MVC框架时写过一篇文章,当时Knockout和Backbone都在用,但之后的项目全是在用Backbone,主要因为它简单、灵活,无论是富JS应用还是企业网站都用得上。相比React针对
View和单向数据流的设计,Backbone更能体现MVC的思路,所以针对它写一篇入门范例,说明如下:
1. 结构上分4节,介绍Model/View/Collection,实现从远程获取数据显示到表格且修改删除;
2. 名为“范例”,所以代码为主,每节的第1段代码都是完整代码,复制粘贴就能用,每段代码都是基于前一段代码来写的,因此每段代码的新内容不会超过20行(大括号计算在内);
3. 每行代码没有注释,但重要内容之后有写具体的说明;
4. 开发环境是Chrome,使用github的API,这样用Chrome即使在本地路径(形如file://的路径)也能获取数据。
0. Introduction
几乎所有的框架都是在做两件事:一是帮你把代码写在正确的地方;二是帮你做一些脏活累活。Backbone实现一种清晰的MVC代码结构,解决了数据模型和视图映射的问题。虽然所有JS相关的项目都
可以用,但Backbone最适合的还是这样一种场景:需要用JS生成大量的页面内容(HTML为主),用户跟页面元素有很多的交互行为。
Backbone对象有5个重要的函数,Model/Collection/View/Router/History。Router和History是针对Web应用程序的优化,建议先熟悉pushState的相关知识。入门阶段可以只了解Model/Collection/View。
将Model视为核心,Collection是Model的集合,View是为了实现Model的改动在前端的反映。
1. Model
Model是所有JS应用的核心,很多Backbone教程喜欢从View开始讲,其实View的内容不多,而且理解了View意义不大,理解Model更重要。以下代码实现从github的API获取一条gist信息,显示到页面
上:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/javascript" src="http://backbonejs.org/backbone-min.js"></script>
<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
</head>
<body>
<table id="js-id-gists" class="table">
<thead><th>description</th><th>URL</th><th>created_at</th></thead>
<tbody></tbody>
</table>
<script type="text/javascript">
var Gist = Backbone.Model.extend({
url: 'https://api.github.com/gists/public',
parse: function (response) {
return (response[0]);
}
}),
gist = new Gist();
gist.on('change', function (model) {
var tbody = document.getElementById('js-id-gists').children[1],
tr = document.getElementById(model.get('id'));
if (!tr) {
tr = document.createElement('tr');
tr.setAttribute('id', model.get('id'));
}
tr.innerHTML = '<td>' + model.get('description') + '</td><td>' + model.get('url') + '</td><td>' + model.get('created_at') + '</td>';
tbody.appendChild(tr);
});
gist.fetch();
</script>
</body>
</html>
LINE4~8: 加载要用到的JS库。ajax请求和部分View的功能需要jQuery支持(或者重写ajax/View的功能);Backbone的代码是基于Underscore写的(或者用Lo-Dash代替);加载bootstrap.css只是因为
默认样式太难看…
LINE16~22: 创建一个Model并实例化。url是数据源(API接口)的地址,parse用来处理返回的数据。实际返回的是一个Array,这里取第一个Object。
LINE24~33: 绑定change事件。还没有使用View,所以要自己处理HTML。这10行代码主要是get的用法(model.get),其他的功能之后会用View来实现。
LINE34: 执行fetch。从远程获取数据,获到数据后会触发change事件。可以重写sync方法
打开Chrome的Console,输入gist,可以看到Model获得的属性:
Model提供数据和与数据相关的逻辑。上图输出的属性是数据,代码中的fetch/parse/get/set都是对数据进行操作,其他的还有escape/unset/clear/destory,从函数名字就大致可以明白它的用途。还有很
常用的validate函数,在set/save操作时用来做数据验证,验证失败会触发invalid事件:
/* 替换之前代码的JS部分(LINE16~34) */
var Gist = Backbone.Model.extend({
url: 'https://api.github.com/gists/public',
parse: function (response) {
return (response[0]);
},
defaults: {
website: 'dmyz'
},
validate: function (attrs) {
if (attrs.website == 'dmyz') {
return 'Website Error';
}
}
}),
gist = new Gist();
gist.on('invalid', function (model, error) {
alert(error);
});
gist.on('change', function (model) {
var tbody = document.getElementById('js-id-gists').children[1],
tr = document.getElementById(model.get('id'));
if (!tr) {
tr = document.createElement('tr');
tr.setAttribute('id', model.get('id'));
}
tr.innerHTML = '<td>'+ model.get('description') +'</td><td>'+ model.get('url') +'</td><td>'+ model.get('created_at') +'</td>';
tbody.appendChild(tr);
});
gist.save();
跟之前的代码比较,有4处改动:
LINE7~9: 增加了defaults。如果属性中没有website(注意不是website值为空),会设置website值为dmyz。
LINE10~14: 增加validate函数。当website值为dmyz时,触发invalid事件。
LINE18~20: 绑定invalid事件,alert返回的错误。
LINE31: 不做fetch,直接save操作。
因为没有fetch,所以页面上不会显示数据。执行save操作,会调用validate函数,验证失败会触发invalid事件,alert出错误提示。同时save操作也会向Model的URL发起一个PUT请求,github这个API没
有处理PUT,所以会返回404错误。
在Console中输入gist.set(‘description', ‘demo'),可以看到页面元素也会有相应的变化。执行gist.set(‘description', gist.previous(‘description'))恢复之前的值。这就是Model和View的映射,现在还是自己实