我一直在关注Addy Osmani的书开发Backbone.js应用程序,the version available online for free.因此,第一个练习是备受吹捧的样本" Todo app",也可以从Backbone的原始文档样本中解脱出来。
当应用程序在将新条目添加到要执行的操作列表时更新视图时,我发现了一个奇怪的错误:当我编辑列表条目并按下回车按钮时,没有任何反应。输入不会失焦,条目中的标签不会自动更新。但是,模型会保存已编辑的条目,因为当我刷新页面时,编辑的条目会显示我对其进行的更改。
我不知道发生了什么,因为视图会听取模型更改。
以下是代码:
app.TodoView = Backbone.View.extend({
tagName: "li",
template: _.template($("#item-template").html()),
events:{
"dblclick label":"edit",
"keypress .edit": "updateOnEnter",
"blur .edit": "close"
},
initalize: function(){
this.listenTo(this.model, "change", this.render);
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
this.myInput = this.$(".edit");
return this;
},
edit: function(){
this.$el.addClass("editing");
this.myInput.focus();
},
close: function(){
var value = this.myInput.val().trim();
if(value) this.model.save({ title: value});
this.$el.removeClass("editing");
},
updateOnEnter: function(x){
if(x.keyCode === 13)
this.close();
}});
app.AppView = Backbone.View.extend({
el: $("#app"),
statsTemplate: _.template($("#stat-template").html()),
events:{
"keypress #newentry": "createOnEnter",
"click #clear-completed": "clearCompleted",
"click #toggle-all": "toggleAllComplete"
},
initialize: function(){
this.allCheck = this.$("#toggle-all")[0];
this.newJob = this.$("#newentry");
this.main = this.$("#main");
this.foot = this.$("#foot");
this.listenTo(app.TodoCol, "add", this.addOne);
this.listenTo(app.TodoCol, "reset", this.addAll);
this.listenTo(app.TodoCol, "change:completed", this.filterOne);
this.listenTo(app.TodoCol, "filter", this.filterAll);
this.listenTo(app.TodoCol, "all", this.render);
app.TodoCol.fetch();
console.log(app.TodoCol.toJSON());
},
addOne: function(todo){
var view = new app.TodoView({model: todo});
$("#items").append(view.render().el);
},
addAll: function(todo){
this.$("items").html("");
app.TodoCol.each(this.addOne, this);
},
filterOne: function(todo){
todo.trigger("visible");
},
filterAll: function(){
app.TodoCol.each(this.filterOne, this);
},
render: function(){
var comp = app.TodoCol.getCompleted().length;
var open = app.TodoCol.getOpen().length;
if(app.TodoCol.length){
this.main.show();
this.foot.show();
this.foot.html(this.statsTemplate({
completed: comp,
remain: open
}));
this.$("#filters li").removeClass("active")
.filter('[href="#/' + ( app.TodoFilter || '' ) + '"]')
.addClass('selected');
}else{
this.main.hide();
this.foot.hide();
}
this.allCheck.checked = !open;
},
newEntry: function() {
return {
title: this.newJob.val().trim(),
order: app.TodoCol.nextOrder(),
completed: false
};
},
createOnEnter: function(event){
if(event.which !== 13 || !this.newJob.val().trim())
return;
app.TodoCol.create(this.newEntry());
this.newJob.val("");
},
clearCompleted: function(){
_.invoke(app.TodoCol.getCompleted(), "destroy");
return false;
},
toggleAllComplete: function(){
var comp = this.allCheck.checked;
app.TodoCol.each(function(t){
t.save({ completed: comp});
});
}});
以下是衡量标准的模型:
app.Todo = Backbone.Model.extend({
defaults:{
title: "",
completed: false
},
toggle: function(){
this.save({completed: !this.get("completed")});
}});
app.List = Backbone.Collection.extend({
model: app.Todo,
localStorage: new Backbone.LocalStorage("todo-backbone"),
getCompleted: function(){
return this.where({completed: true});
},
getOpen: function(){
return this.where({completed: false});
},
nextOrder: function(){
if(!this.length) return 1;
return this.last().get("order") + 1;
},
comparator: function(todo){
return todo.get("order");
}});
请帮助我!