使localStorage中的Backbone.js项目具有唯一性?

问题描述:

我在我的收藏中有一个重复检查,我重写了添加功能,它似乎一直工作,直到页面刷新。使localStorage中的Backbone.js项目具有唯一性?

重复被阻止,并显示“您已将此项目添加到待办事项列表!但它看起来像刷新页面时,副本以任何方式添加到localStorage。希望解决这个问题 - 在这个问题上过去几天一直在挠头。

下面我收藏:

app.TodoList = Backbone.Collection.extend({ 
    model: app.Todo, 
    localStorage: new Store("backbone-todo"), 
    completed: function() { 
    return this.filter(function(todo){ 
     return todo.get('completed'); 
    }); 
    }, 
    remaining: function(){ 
    return this.without.apply(this, this.completed()); 
    } 
}); 

app.TodoList.prototype.add = function(todo) { 

var isDupe = this.any(function(_todo){ return _todo.get('title').toLowerCase() === todo.get('title').toLowerCase(); 
}); 

return isDupe ? alert("You've already added this item to the todo list!") : Backbone.Collection.prototype.add.call(this, todo);} 


// instance of the Collection 
app.todoList = new app.TodoList(); 

这里是模型:

app.Todo = Backbone.Model.extend({ 
    defaults: { 
    title: '', 
    completed: false 
    }, 
    toggle: function(){ 
    this.save({ completed: !this.get('completed')}); 
    } 
}); 

的观点:

app.TodoView = Backbone.View.extend({ 
    tagName: 'li', 
    template: _.template($('#item-template').html()), 
    render: function(){ 
    this.$el.html(this.template(this.model.toJSON())); 
    this.input = this.$('.edit'); 
    return this; // enable chained calls 
    }, 
    initialize: function(){ 
    this.model.on('change', this.render, this); 
    this.model.on('destroy', this.remove, this); // remove: 'Convenience Backbone' 
    }, 
    events: { 
    'dblclick label' : 'edit', 
    'keypress .edit' : 'updateOnEnter', 
    'blur .edit' : 'close', 
    'click .toggle' : 'toggleCompleted', 
    'click .destroy' : 'destroy' 
    }, 
    edit: function(){ 
    this.$el.addClass('editing'); 
    this.input.focus(); 
    }, 
    close: function(){ 
    var value = this.input.val().trim(); 
    if(value) { 
    this.model.save({ title: value }); 
    } 
    this.$el.removeClass('editing'); 
    }, 
    updateOnEnter: function(e){ 
    if(e.which == 13){ 
     this.close(); 
    } 
    }, 
    toggleCompleted: function(){ 
    this.model.toggle(); 
    }, 
    destroy: function(){ 
    this.model.destroy(); 
    } 
}); 

// renders the full list of todo items calling TodoView for each one. 
app.AppView = Backbone.View.extend({ 
    el: '#todoapp', 
    initialize: function() { 
    this.input = this.$('#new-todo'); 
    app.todoList.on('add', this.addAll, this); 
    app.todoList.on('reset', this.addAll, this); 
    app.todoList.fetch(); // Loads list from local storage 
    }, 
    events: { 
    'keypress #new-todo': 'createTodoOnEnter' 
    }, 
    createTodoOnEnter: function(e){ 
    if (e.which !== 13 || !this.input.val().trim()) { // ENTER_KEY = 13 
     return; 
    } 
    app.todoList.create(this.newAttributes()); 
    this.input.val(''); // clean input box 
    }, 
    addOne: function(todo){ 
    var view = new app.TodoView({model: todo}); 

    $('#todo-list').append(view. 
     render().el); 

    }, 
    addAll: function(){ 
    this.$('#todo-list').html(''); // clean the todo list 
    // filter todo item list 
    switch(window, filter){ 
     case 'pending': 
      _.each(app.todoList.remaining(), this.addOne); 
      break; 
     case 'completed': 
      _.each(app.todoList.completed(), this.addOne); 
      break; 
     default: 
      app.todoList.each(this.addOne, this); 
      break; 
    } 
    }, 
    newAttributes: function(){ 
    return { 
     title: this.input.val().trim(), 
     completed: false 
    } 
    } 
}); 

路由器:

app.Router = Backbone.Router.extend({ 
    routes: { 
    '*filter' : 'setFilter' 
    }, 
    setFilter: function(params){ 
    console.log('app.router.params = ' + params); 
    window.filter = params.trim() || ''; 
    app.todoList.trigger('reset'); 
    } 
}) 

而且初始化:

app.router = new app.Router(); 
Backbone.history.start(); 
app.appView = new app.AppView(); 

如果需要任何更多信息,会很乐意提供。谢谢!

在Backbone中,当您调用create时,调用add和save。在这里阅读源代码:http://backbonejs.org/docs/backbone.html#section-113

因此,您阻止添加发生,但添加副本时仍然发生保存。

您可以使用内置的验证骨干来完成你试图做:

app.Todo = Backbone.Model.extend({ 
    defaults: { 
    title: '', 
    completed: false 
    }, 
    initialize: function() { 
    this.on('error', function(model, error) { 
     alert(error); 
    }); 
    }, 
    toggle: function(){ 
    this.save({ completed: !this.get('completed')}); 
    }, 
    validate: function(attrs, options) { 
    if (this.collection.isExistingTodoTitleOnOtherTodo(attrs)) { 
     return "You've already added this item to the todo list!"; 
    } 
    } 
}); 

app.TodoList = Backbone.Collection.extend({ 
    model: app.Todo, 
    localStorage: new Store("backbone-todo"), 
    completed: function() { 
    return this.filter(function(todo){ 
     return todo.get('completed'); 
    }); 
    }, 
    remaining: function(){ 
    return this.without.apply(this, this.completed()); 
    }, 
    isExistingTodoTitleOnOtherTodo: function(attrs) { 
    return this.any(function(todo) { 
     var titleMatch = todo.get('title').toLowerCase() === attrs.title.toLowerCase(); 
     var idMatch = attrs.id === todo.id; 

     return titleMatch && !idMatch; 
    }); 
    } 
}); 

顺便说一句,你的主干是过时的,因此网站上的文档不反映你可以在你的代码做什么。