1. 程式人生 > >Backbone系列:todo的demo

Backbone系列:todo的demo

  • 模型與檢視的建立:在初始化的時候,自動載入儲存的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