在 《 Backbone 应用实例 》 这个课程里面,我们会一起用 JavaScript 做一个小应用,它可以管理任务列表,应用可以创建新任务,编辑还有删除任务等等。这个实例非常好的演示了使用 JavaScript 来开发富应用,它也能让你对 JavaScript 有一个更好的理解。所以,我们接下来会分成几天,把这个小应用的功能,分成几个部分,介绍每个小功能的细节。跟着这篇文章,或者 《 Backbone 应用实例 》 这个课程,动手练习一下。效果会非常好。
在文章里面,我会把需要的代码粘出来,不过我建议你不要直接去复制跟粘贴。每一个目录,每一个文件,每一行代码,最好可以亲自动手去做出来。这期间我们也会不断的回到浏览器上去测试,这样你能更好的理解,每个步骤的作用。每一个动作,都要动手去试一下。
介绍
在开始之前,最好可以了解一点 JavaScript,jQuery,还有 Backbone 。不过,不懂也没关系,跟着这个练习去实践,不懂的地方,可以再单独去解决一下。我会在练习中提到,代码的具体的意思是什么。
要做的这个小应用,可以管理任务列表,我们需要给应用程序一个结构,也就是把应用分成几个部分,在不同的部分里面,去撰写不同的代码,这样会更容易维护一些。提供这个结构可以使用 Backbone 这个类库。在 《 基于 MVC 的 JavaScript Web 富应用开发 》 这本书里介绍了这款优秀的类库。它可以跟 jQuery 还有 Underscore 很好的结合到一块儿使用,在这个应用实例里面会用到这几样东西。
下面,我们先去创建应用需要的目录和文件结构。
目录结构
根据下面的这个树形结构去创建对应的目录还有文件。应用只有一个页面,就是 index.html ,它是应用的主页。
js 目录里面是应用的主要的代码,这个目录里面,按照功能又分别创建了几个目录,Models 里面是应用的模型,Collections 里面是集合,Views 里面是视图,Routers 里面是路由器。在 js 根目录下的 app.js ,这个文件里会存储启动应用需要的一点代码。这些东西在后面,我们会一点一点去添加。
lib 这个目录里面是应用需要的各种类库,jQuery,Underscore,Backbone,另外还有一个 Backbone 的小插件,backbone.localStorage.js。这个插件的作用就是,会用浏览器的 Local Storage 来存储数据。用 bing.com 或 google.com 去搜索一下这些东西,然后把它们下载下来,放到 lib 这个目录的下面。
assets 里面是应用需要的一点资源,一个样式表,还有一张背景图片。在这篇文章的附件里面,你可以下载到这两个资源。
. ├── assets │ ├── base.css │ └── bg.png ├── index.html ├── js │ ├── Collections │ │ └── TodoCollection.js │ ├── Models │ │ └── Todo.js │ ├── Routers │ │ └── Router.js │ ├── Views │ │ ├── AppView.js │ │ └── TodoView.js │ └── app.js └── lib ├── backbone-min.js ├── backbone.localStorage.js ├── jquery-2.1.1.min.js └── underscore-min.js
主页的基本结构
打开应用根目录下的 index.html,在这个文档里面,需要设计一下应用需要的界面,去定义数据的模板,链接需要的样式表,依赖的库文件,还有即将要用到的 JavaScript 代码文件。选择一款简单的编辑器,比如 Brackets 编辑器,然后输入下面这些代码:
<!doctype html> <html lang="zh-hans"> <head> <meta charset="UTF-8"> <title>Todos</title> <link rel="stylesheet" href="https://ninghao.net/assets/base.css"> </head> <body> <!-- 需要的各种类库 --> <script src="https://ninghao.net/lib/jquery-2.1.1.min.js"></script> <script src="https://ninghao.net/lib/underscore-min.js"></script> <script src="https://ninghao.net/lib/backbone-min.js"></script> <script src="https://ninghao.net/lib/backbone.localStorage.js"></script> <!-- 应用的代码 --> <script src="https://ninghao.net/js/Models/Todo.js"></script> <script src="https://ninghao.net/js/Collections/TodoCollection.js"></script> <script src="https://ninghao.net/js/Views/TodoView.js"></script> <script src="https://ninghao.net/js/Views/AppView.js"></script> <script src="https://ninghao.net/js/Routers/Router.js"></script> <script src="https://ninghao.net/js/app.js"></script> </body> </html>
应用界面需要的代码
接下来,在这个 index.html 里面,需要去设计一下应用需要的界面的 HTML 代码。这个界面的样式,已经在 assets/base.css 这个样式表里面定义好了。你可以直接把下面这些代码,放到 index.html 里面的 body
标签里面。这些代码构建起了应用的界面。
先了解这里面的其中的几个元素:
- #todoapp,它是包装应用界面的一个容器。
- #new-todo,这是一个 text 类型的 input 元素,就是一个文本框,用户可以在里面输入内容,来创建新的任务。
- #todo-list,它是一个用来显示任务列表的地方。
保存一下,然后在浏览器里面去预览一下,直接打开这个 index.html 。
<div id="todoapp"> <!-- 页头部分 --> <header id="header"> <h1>todos</h1> <!-- 创建任务用的文本框 --> <input type="text" id="new-todo" placeholder="需要做点什么呢?" autofocus> </header> <!-- 主体部分 --> <section id="main"> <!-- 标记所有任务为完成状态 --> <input type="checkbox" name="toggle-all" id="toggle-all"> <label for="toggle-all">标记全部为完成</label> <!-- 显示任务列表的地方 --> <ul id="todo-list"></ul> </section> <!-- 页脚部分:还剩多少个没完成的任务,导航,清空完成的任务 --> <footer id="footer"></footer> </div> <div id="info"> <p>双击可以编辑任务</p> </div>
创建模型 - 表示任务数据
模型在 Backbone 里面,是用来表示数据的。 在我们的这个小应用里面,需要处理的数据是任务,这个任务就可以是一个模型,给这个任务模型起个合适的名字,比如 Todo 。
打开 js/Models/Todo.js,在这个文件里面,我们去定义这个任务模型:
var app = app || {}; /** * 模型 Model * * 创建一个叫 Todo 的模型来表示任务数据 */ app.Todo = Backbone.Model.extend({ defaults: { title: '', completed: false } });
在文件的一开始,定义了一个叫 app 的对象,它有点像是一个命名空间,就是我们在全局范围内,只定义了一个东西,就是这个对象。这样不容易跟第三方的代码库发生命名的冲突。 在应用里面,需要用到的其它的东西,都可以作为这个 app 对象的一个属性。
var app = app || {};
app.Todo,就是定义好的用来表示任务数据的模型。在这个模型里面,用到了一个 defaults
属性,在这个属性里面,可以为模型添加默认的属性。title
,表示任务的标题,completed
,表示任务的完成的状态。如果它的值是 true ,就表示任务已经完成了,如果它的值是 false ,表示任务还在进行中,默认我们让它的值默认等于 false。
创建集合 - 表示任务的列表
打开 js/Collections/TodoCollection.js。在这个文件里面,去定义表示任务列表的集合。app.TodoCollection 就是为应用创建的一个集合,跟这个集合对应的模型就是前面创建的 app.Todo 。
var app = app || {}; /** * 集合 Collection */ app.TodoCollection = Backbone.Collection.extend({ // 指定与这个集合相关的模型 model: app.Todo, // 使用 Backbone 的 LocalStorage // 为存储的数据添加一个 todo 前缀 localStorage: new Backbone.LocalStorage('todo') }); // 实例化一下 TodoCollection 这个集合 app.todoList = new app.TodoCollection;
在 Backbone 的集合里面, 有一些方法,可以保存,删除,提取数据模型。比如可以把数据存储到指定的数据源里面,我们也可以从指定的数据源那里把数据提供出来,然后把它添加到这个表示任务列表的集合里面。这些动作用的就是 jQuery 的 Ajax 方法。我们可以为应用提供一个处理数据的后台程序,比如可以使用 Drupal ,WordPress 或者 Laravel 等等。
不过,在这个小应用里面,我们使用了 Backbone 的 Local Storage 插件( backbone.localStorage.js ),它会覆盖掉 Backbone 的 Sync 方法。用了这个小插件以后,Backbone 会把数据放到浏览器的 Local Storage 里面,也就是放到用户的本地浏览器里面存储起来。
localStorage: new Backbone.LocalStorage('todo')
这行代码的作用就是去使用 Backbone 的这个 Local Storage 插件,同时指定了一下数据的前缀。这里的 todo ,就是存储的数据的前缀,也可以把它想像成是一个命名空间,也就是为了避免冲突,为要存储的数据起的一个名字。
app.todoList = new app.TodoCollection;
上面这行代码的功能是实例化了一下创建的这个集合。这样在应用的其它地方,可以用到 app.todoList 这个集合对象。
练习
下面,去做几个练习,来理解一下集合,模型,还有 Backbone 的 Local Storage 插件。
- 在 Chrome 浏览器里打开应用程序的主页,index.html。
- 打开浏览器的控制台,也就是 console(Mac:alt + command + J,Windows:alt + ctrl + J)。
- 输入 app.todoList,回车。查看一下应用里面的集合。
- 观察在控制台上返回的结果,注意 length 属性的值,现在应该是 0 ,表示在这个集合里面,还没有任何的模型。
- 输入 app.todoList.create({title: '发布新的课程'})。
- 再查看一下 app.todoList 。
- 观察返回的结果,你会发现,length 属性的值会是 1 ,表示集合里面已经有了一个模型。
- 打开 Resources 选项卡。
- 找到 Local Storage,再打开 file:// 这个路径下面的 Local Storage。
- 观察存储在 Local Storage 里面的数据。
我们先在控制台上查看了一下 app.todoList 这个集合里的东西,发现里边儿啥也没有。然后用集合的 create 这个方法去创建了一个任务模型,指定了一个任务的 title 属性的值,这个模型会被添加到集合里面,同时也会存储到指定的数据源里面,这里就是把创建的任务存储到了浏览器的 Local Storage 里面了。
再做一个练习:
- 刷新一下 index.html 这个页面。
- 在控制台里面再输入一次 app.todoList。
- 观察返回的结果,你会看到集合里啥也没有了。
- 输入 app.todoList.fetch()。
- 再输入一次 app.todoList,观察得到的结果。
- 再输入 app.todoList.at(0).attributes,观察得到的结果。
- 再输入 app.todoList.at(0).destroy()。
- 最后再看一下 app.todoList,观察返回的结果。
- 打开 Resources 选项卡,Local Storage ,观察存储在本地上的数据。
在这个练习里,刷新页面以后,集合里就没有东西了。然后用集合的 fetch() 这个方法,重新从数据源那里把模型提取出来,再放到 app.todoList 这个集合里面。在这里提供数据的数据源就是浏览器的本地存储(Local Storage)。这时再次查看集合的时候,你会看到它里面又有了一个模型。
集合的 at 这个方法,可以查看集合里面指定位置上的模型,0 表示集合里的第一个模型,后面的 attributes 这个属性,可以去查看模型里面的属性。
在第 7 步里,调用了集合里的模型的 destroy() 这个方法,它的作用就是,销毁并删除模型。所以,再次查看集合的时候,length 属性的值又会变成了 0 ,同时,也会把存储在浏览器的 Local Storage 里面的东西也删除掉了。
评论
太好了,是我这种级别想要的,谢谢皓哥!大赞!
10 年 5 个月 以前
谢谢啊。呵呵。那就我继续写完。
10 年 5 个月 以前
视频非常不错啊!但是有两点:1.声音太温柔了。2.为什么订要一年地订啊?多点付费选择不行?
10 年 5 个月 以前
嘿嘿。声音太温柔,因为人比较腼腆。一年一年的订是因为,需要一年的时间才行学到点东西。
10 年 5 个月 以前
按照文字教程做,在console里面输入app.todoList会提示undefined...
10 年 3 个月 以前
又自己搞定...
10 年 3 个月 以前