使localStorage中的Backbone.js项目独一无二?

时间:2014-12-11 01:48:44

标签: javascript backbone.js backbone-local-storage

我在我的收藏中有一个欺骗检查,我在这里覆盖了添加功能,它似乎一直工作直到页面刷新。

重复项被屏蔽,并显示“您已将此项目添加到待办事项列表!”但似乎在页面刷新时,副本会以任一方式添加到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();

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

1 个答案:

答案 0 :(得分:1)

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

所以你阻止了添加的发生,但是在添加副本时仍然发生了保存。

您可以使用Backbone的内置验证来完成您尝试执行的操作:

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;
    });
  }
});
顺便说一下,你的Backbone已经过时,因此网站上的文档并不能反映你在代码中可以做些什么。