【问题标题】:backbone model save issue骨干模型保存问题
【发布时间】:2012-04-24 05:52:06
【问题描述】:

我一周前才开始研究骨干网,如果这个问题很愚蠢,请不要介意。好的,这就是我想要做的。

我有一个名为 Item 的模型和一个名为 Items 的集合。有两种视图,一种用于添加项目,另一种用于列出项目。我遇到的问题是当我尝试保存该项目时,它第一次被正确保存。下次我添加新项目时,该项目已成功创建,但之前添加的项目也会更新为新项目的属性。这发生在所有被添加的连续项目上。

我猜我集合中的所有模型都在更新,或者我需要有自己的保存方法。我实际上无法弄清楚我做错了什么。我只想用视图保存有问题的模型,而不是集合中的所有模型。非常感谢一些指针。

链接到demo

项目添加/编辑视图

define([
  'jquery',
  'use!underscore',
  'use!backbone',
  'mustache',
  'models/item',
  'views/bootstrap',
  'text!templates/items/edit.mustache',
  'text!templates/items/new.mustache',
  'handlebars',
  'bootstrap'

], function($, _, Backbone, Mustache, Item, Bootstrap, editTemplate, newTemplate, Handlebars){

  var app = new Backbone.Router

  var ItemEditView = Backbone.View.extend({

    el: $('#page'),

    events: {
      'submit #new-item': 'saveItem',
      'click .cancel': 'cancelItem'
    },

    initialize: function(options){
      if (!this.model.isNew()) {
        this.model.bind('change', this.render, this)
        this.model.fetch()
      }
    },

    render: function(){
      var item = this.model.attributes
      var template = this.model.isNew() ? newTemplate : editTemplate
      var compiledTemplate = Mustache.render(template, item )
      $(this.el).html(compiledTemplate)
      if (this.model.isNew()) $('#itemName').focus()
      return this
    },


    /*
     *  Event actions
     */

    saveItem: function(e) {
      e.preventDefault()

      var item = {
        name: $('#itemName').val(),
        price: $('#itemPrice').val()
      }
      var self = this
      this.model.save(item, {
        success: function (model, response) {
          app.navigate('items/'+model.id, {trigger: true, replace: true})
        },
        error: function (model, response) {
          new Bootstrap.alert({ el: $('#page') }).render(response, 'error')
        }
      })
    },

    cancelItem: function (e) {
      if (this.model.isNew())
        app.navigate('items', {trigger: true, replace: true})
      else
        app.navigate('items/'+this.model.id, {trigger: true, replace: true})
    }

  })

  return ItemEditView
})

物品型号

define([
  'use!underscore',
  'use!backbone'
], function(_, Backbone) {
  var Item = Backbone.Model.extend({

    urlRoot: 'api/items',

    idAttribute: '_id'

  });

  return Item;
});

项目集合

define([
  'jquery',
  'use!underscore',
  'use!backbone',
  'models/item'
], function($, _, Backbone, Item){
  var Items = Backbone.Collection.extend({

    model: Item,

    url: 'api/items/'

  });

  return Items;
});

链接到Source code(以防万一)

【问题讨论】:

  • 从您在此处列出的代码中不清楚您在哪里向您的项目集合添加新的“项目”。我会推荐的一件事是将模型逻辑移出视图并移入模型中。如果由于视图中发生的事件而需要更新模型,则只需从视图中调用模型上的方法来执行所需的逻辑。
  • 好的,我会试试的。我没有放完整代码的原因是因为它是模块化的,保存在不同的文件夹和文件中。这是complete code的链接
  • 我不需要指向代码的链接,而是需要一些关于您将新“项目”添加到项目集合的位置的方向。

标签: javascript backbone.js


【解决方案1】:

当您使用完表单后,无论是提交还是取消表单,您都必须通过调用 ItemView.remove() 或至少取消委托事件来销毁或取消视图:

saveItem: function(e) {
  e.preventDefault()

  var item = {
    name: $('#itemName').val(),
    price: $('#itemPrice').val()
  }
  var self = this
  this.model.save(item, {
    success: function (model, response) {
      app.navigate('items/'+model.id, {trigger: true, replace: true})
    },
    error: function (model, response) {
      new Bootstrap.alert({ el: $('#page') }).render(response, 'error')
    }
  })
  this.remove(); // undelegate events for later views.
},

cancelItem: function (e) {
  if (this.model.isNew())
    app.navigate('items', {trigger: true, replace: true})
  else
    app.navigate('items/'+this.model.id, {trigger: true, replace: true});
  this.remove(); // undelegate events for later views.
} 

由于事件被委托给#page,并且您的旧视图在创建新视图后仍然存在,因此它们的保存和取消方法仍将触发,直到它们被删除。

【讨论】:

  • 我应该补充一点,您应该有 1 个 ItemCollection,而不是每次需要时都重新创建它。将节省您往返服务器的次数。除此之外,到目前为止看起来还不错!
  • 嘿,非常感谢!这解决了问题!这类事情一般是怎么处理的?从 DOM 中删除视图不会一直有效
  • 我用this.undelegateEvents();代替this.remove()
猜你喜欢
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2015-03-19
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
相关资源
最近更新 更多