Backbone.js:View不反映Todo App中的模型更改

时间:2014-07-26 01:48:28

标签: javascript backbone.js backbone-views

我一直在关注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");
}});

请帮助我!

0 个答案:

没有答案