1

我的收藏中有一个重复检查,我在其中覆盖了 add 函数,它似乎可以工作,直到页面刷新。

重复项被阻止并显示“您已将此项目添加到待办事项列表!”的警告。但似乎当页面刷新时,无论哪种方式,副本都会添加到 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();

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

4

1 回答 1

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 已过时,因此网站上的文档无法反映您可以在代码中执行的操作。

于 2014-12-11T05:54:23.573 回答