Backbone系列:todo的demo

本文介绍如何使用Backbone.js框架构建一个具备增删改查功能的Todo应用。包括模型与视图的基本创建、与数据存储的配合以及实现丰富的交互功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

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

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








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值