骨干模型保存,验证失败

时间:2012-12-30 09:28:30

标签: backbone.js coffeescript

没有任何谷歌搜索能够解决我的困惑,所以我想我会在这里问这个问题。

我正在尝试保存模型并使用成功/错误回调。在backbone documentation上,它表示您保存模型,如下所示:model.save([attributes], [options])

我无法在文档上的任何地方找到告诉你如何保存整个模型(即没有指定属性),但是遇到了this question,其中第二个答案是保存你可以做的整个模型{ {1}}。

但是我这样做无济于事。我的代码如下:

骨干模型:

model.save({}, [options])

在我看来,我有以下功能:

class Student extends Backbone.Model
  url: ->
    '/students' + (if @isNew() then '' else '/' + @id)

  validation:
    first_name:
      required: true
    last_name:
      required: true
    email:
      required: true
      pattern: 'email'

  schema: ->
    first_name:
      type: "Text"
      title: "First Name"
    last_name:
      type: "Text"
      title: "Last Name"
    email:
      type: "Text"
      title: "Email"

在保存之前的第一个console.log中,通过class Students extends CPP.Views.Base ... saveModel = -> console.log "model before", @model.validate() console.log "model attrs", @model.attributes @model.save {}, wait: true success: (model, response) -> notify "success", "Updated Profile" error: (model, response) => console.log "model after", @model.validate() console.log "model after is valid", @model.isValid() console.log "response", response notify "error", "Couldn't Update" 响应的方式告诉我该模型是有效的。如果我确实看到模型,我可以看到所有三个字段都已填写。

同样,错误undefined@model.validate()中的下两个控制台日志分别返回@model.isValid()undefined。 但是,我尝试保存模型时得到的响应是true

最后在我得到的models属性的console.log中:

Object {first_name: "First name is required", last_name: "Last name is required", email: "Email is required"}

这让我相信,当我将Object created_at: "2012-12-29 23:14:54" email: "email@email.com" first_name: "John" id: 2 last_name: "Doe" type: "Student" updated_at: "2012-12-30 09:25:01" __proto__: Object 传递给我的模型时,它实际上是试图将属性保存为nil,否则为什么还会出错呢?

有人可以指出我做错了什么吗?我宁愿不必将每个属性单独传递给save!

提前致谢

2 个答案:

答案 0 :(得分:1)

您确定在save之前是否已正确设置模型的属性?即使没有设置任何属性,它仍然可以通过validate(取决于validate函数的定义方式)。请尝试在控制台中打印模型以验证。顺便说一下,最好在null中传递{}而不是save,这样就不会调用模型的set方法。

更新:

根据Backbone的源代码,如果将null作为save的第一个参数传递,则模型的属性将保持不变,直到模型已成功保存在服务器上。所以另一种可能性是您的服务器已成功保存模型但返回了损坏的对象,导致模型的set方法失败。如果仍然无法解决问题,则跟踪model.set方法可能会有所帮助。

答案 1 :(得分:1)

根据Hui Zheng的建议答案,我在服务器中修改了控制器,以JSON格式返回学生。

然而,为了找到问题的真正根源,我在保存时阅读backbone documentation,并发现当wait: true作为选项提供时,它会执行以下操作:

if (!done && options.wait) {
        this.clear(silentOptions);
        this.set(current, silentOptions);
}

进一步调查清楚我找到了

clear: function(options) {
  var attrs = {};
  for (var key in this.attributes) attrs[key] = void 0;
  return this.set(attrs, _.extend({}, options, {unset: true}));
},

从这看起来好像每个属性都被清除然后被重置。但是,在清除我的模型时,我写的验证将失败(因为first_namelast_nameemail是必需的。)

backbone.validation documentation我们被告知我们可以使用参数forceUpdate: true,所以我在保存模型时选择使用它。我现在要假设(虽然这可能不是一个好习惯)来自服务器的数据是正确的,因为这也已得到验证。

因此我的最终代码是:

saveModel = ->
  @model.save {},
    wait: true
    forceUpdate: true
    success: (model, response) ->
      notify "success", "Updated Profile"
    error: (model, response) ->
      notify "error", "Couldn't Update"