您的位置:首页 > 其它

Backbone系列:todo的demo

2015-11-08 16:29 387 查看

概述

todo的思想是:Model作为每个todo项的模型,而且每个todo项与一个TodoView关联(只渲染li的视图)。最后在AppView上监听整个todo的变更,触发对应的事件。
简略的demo

step1

首先我们从只有简单的添加功能的todo做起
var Todo = Backbone.Model.extend({
// 这里不定义也可以,不过以后和Collection的create方法配合的话,需要默认的属性
defaults: {
title: 'todo项的标题',
done: false
}
});

var TodoList = Backbone.Collection.extend({
// 用模型类覆盖!
model: Todo
});
var todolist = new TodoList();

var TodoView = Backbone.View.extend({
tagName: 'li',
template: _.template($('#item-template').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});

var AppView = Backbone.View.extend({
el: $('#todoapp'),
events: {
'keypress #new-todo': 'create'
},
initialize: function () {
this.input = $('#new-todo');
// add事件的API为:'add'(model, collectoin, options)
// 所以会自动把model实例传进方法里
this.listenTo(this.collection, 'add', this.addOne);
},
create: function(e) {
if (e.keyCode != 13 || !this.input.val()) {
return false;
}
this.collection.add({
title: this.input.val(),
// 没有使用create方法,需要自己设置done属性
done: false
});
this.input.val('');
},
addOne: function (todo) {
var view = new TodoView({model: todo});
// 这里取$el和el都可以,只是append是jquery对象或htmlElement对象的区别
$("#todo-list").append(view.render().el);
}
});
var app = new AppView({collection: todolist});
一共分为四个模块:对应每个todo项的模型(Todo)和视图(TodoView),用于统一储存多个todo项的集合(TodoList),以及用于监听变更的视图(AppView)

配合数据储存

Backbone自定义的Backbone.sync能将模型或集合的状态,持续性的同步到服务器端。在这里我们用不同的持久化方案即用localStorage把数据储存到本地,我们需要做的只是在Collection中定义localStorage属性
localStorage: new Backbone.LocalStorage("todos-backbone")
然后我们就能使用create和save等方法把数据储存在本地,并且触发add事件,完成模型的新增与储存

丰富交互功能

模型与视图的创建:在初始化的时候,自动加载储存的todo项,并单向绑定todo项的数量与视图,关键点在AppView。demo
在AppView视图初始化时,调用集合的fetch()方法加载储存的数据
fetch()方法获得todo的模型数据,会自动添加到集合中,并触发集合的"add"事件,渲染对应todo项的视图
模型添加到集合时,也会触发"all"事件,我们可以在这里更新todo项数量统计的视图

var AppView = Backbone.View.extend({
el: $('#todoapp'),
statsTemplate: _.template($('#stats-template').html()),
events: {
'keypress #new-todo': 'create'
},
initialize: function () {
this.input = $('#new-todo');
// add事件的API为:'add'(model, collectoin, options)
// 所以会自动把model实例传进方法里
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'all', this.render);

this.footer = this.$('footer');
this.main = $('#main');

// 自动从数据库拉取模型,然后使用set方法
// set方法触发集合的add事件,调用addOne方法,所以内容被加载
this.collection.fetch();
},
render: function () {
// 调用集合方法,获得当前已完成和未完成todo项的数量
var done = this.collection.getDone().length;
var remaining = this.collection.getRemaining().length;

if (this.collection.length) {
this.main.show();
this.footer.show();
this.footer.html(this.statsTemplate({
done: done,
remaining: remaining
}));
}
else {
this.main.hide();
this.footer.hide();
}
},
create: function(e) {
if (e.keyCode != 13 || !this.input.val()) {
return false;
}
this.collection.add({
title: this.input.val(),
// 没有使用create方法,需要自己设置done属性
done: false
});
this.input.val('');
},
addOne: function (todo) {
var view = new TodoView({model: todo});
// 这里取$el和el都可以,只是append是jquery对象或htmlElement对象的区别
$("#todo-list").append(view.render().el);
}
});

模型与视图的删除:监听todo项目清除和全部清除,并调用视图TodoView上的对应方法删除DOM。关键点在TodoView上事件的监听的定义。demo
在TodoView上监听destroy按钮的点击事件,并使TodoView监听model上的destory事件
点击destory时调用model的destory()方法,删除集合中的模型,并调用视图的remove方法删除DOM
在AppView上监听全部删除的按钮,使用_.invoke()方法删除所有状态为已完成的todo项

var TodoView = Backbone.View.extend({
tagName: 'li',
template: _.template($('#item-template').html()),
events: {
'click .toggle': 'toggleDone',
'click a.destroy': 'clear'
},
initialize: function() {
// 但model触发destory事件时,调用视图的remove方法,从DOM中移除对应视图
this.listenTo(this.model, 'destroy', this.remove);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
toggleDone: function() {
// 因为在实例化app的时候,已经把todo传进来作为这个view的model
this.model.toggle();
},
clear: function() {
this.model.destroy();
}
});

模型与视图的更新:在更新model后,使用save方法就能更新模型。demo
在TodoView中绑定双击事件,在双击后允许更改内容
在失焦后更新模型

var Router = Backbone.Router.extend({
routes: {
'*filter': 'setFilter'
},
setFilter: function(param) {
state = param || '';
todolist.trigger('filter');
}
});
var router = new Router();
Backbone.history.start();

在路由上监听,并触发collection的filter事件,view监听collection的事件并更新视图demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: