2012-06-11 138 views
4

据有关验证它指出骨干文档验证的发送请求:骨干验证失败时

如果验证返回一个错误,设置和保存不会继续,并且 模型属性不会被修改。

因此,如果验证失败,我读取该设置或保存的方式应该永远不会运行。但那不是我得到的结果。即使验证失败,它仍然会发送POST/PUT请求。我是否阅读文档错误或在代码中做了不正确的事情?

这里是我的相关代码: https://gist.github.com/80f6ef0099fbe96025dc

App.Models.Test = Backbone.Model.extend(
    urlRoot: '/api/test' 

    validate: (attrs) -> 
     errors = [] 
     if attrs.to is '' 
      errors.push 
       name: "to" 
       field: "js-to" 
       message: "You must enter a to address" 
     if attrs.subject is '' 
      errors.push 
       name: "subject" 
       field: "js-subject" 
       message: "You must enter a subject" 

     # Return our errors array if it isn't empty 
     errors if errors.length > 0 
) 

App.Views.Details = Backbone.View.extend(
    initialize: -> 
     @model.bind "error", @error, this 

    events: 
     "click #js-save": "saveItem" 

    saveItem: (e) -> 
     e.preventDefault() 

     # Set the model then save it. 
     @model.set 
      subject: $("#js-subject").val() 
      message: $("#js-message").val() 
      mailbox_id: $("#js-from").val() 
      to: $("#js-to").val() 
      cc: $("#js-cc").val() 
      bcc: $("#js-bcc").val() 
      tags: App.Helpers.tagsToObject $('#js-tags').val() 
      scope: $('#js-scope').val() 
      attachments: attachments 

     @model.save null, 
      success: (model, response) => 
       App.Helpers.showAlert "Success!", "Saved Successfully", "alert-success" 
       @next() 
      error: (model, response) -> 
       App.Helpers.showAlert "Error", "An error occurred while trying to save this item", "alert-error" 

    # Show the errors based on validation failure. 
    error: (model, error) -> 
     App.Helpers.displayValidationErrors error 
+0

我认为这可以很容易地修复在文档中。只设置触发器验证。如果保存提供了属性,它也会触发保存。 –

回答

5

这样做可以节省您的模型:

@model.save null, 
    success: -> ... 
    error: -> ... 

null是你的麻烦的来源,使用{}事情会开始表现更好;如果你把你的@model.set@model.save电话,事情会更好:

attrs = 
    subject: $("#js-subject").val() 
    #... 
@model.save attrs, 
    success: -> ... 
    error: -> ... 

一个save调用如下:

保存model.save([attributes], [options])
[...]
属性散列(如在set中)应该包含您想要更改的属性

因此,将null传递给attributes意味着您要保存模型原样。

当你save模型,验证主要是留给setcode looks like this

if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) { 
    return false; 
} 

attrsnull所以set不会被调用;然而,如果你让save处理你的set,你会得到你以后的行为。如果你通过了wait: true选项,savemanually run the validation上传递的属性:

if (options.wait) { 
    if (!this._validate(attrs, options)) return false; 
    ... 
} 

内部_validate方法是validate的包装,做一些簿记和错误处理。你没有使用wait: true,所以这不适用于你,但我认为这值得一提。

考虑一个简单的例子,其模型的validate总是失败。如果你这样说:

@model.on 'error', @error 
@model.save attrs, 
    success: -> console.log 'AJAX success' 
    error: -> console.log 'AJAX error' 

然后@error将被调用,因为save将最终调用setsome attributesset将调用validate。演示:http://jsfiddle.net/ambiguous/HHQ2N/1/

但是,如果你说:

@model.save null, ... 

nullwill cause the set call to be skipped。演示:http://jsfiddle.net/ambiguous/6pX2e/(这里的AJAX将失败)。

@model.set通话权之前@model.save应触发你的错误处理,但如果你没有检查什么@model.set回报,执行会盲目继续到save电话咨询,谈谈你的服务器。


总之,你有三件事情会在这里:

  1. 你不叫他们save方式,你应该。
  2. 您忽略了@model.set的返回值,并且失去了捕获验证错误的机会。
  3. 骨干的处理save(null, ...)的说法可能会更好,但我不知道是否值得花费一种奇怪的方式来调用它。

您应该将set/save对组合逼到save或检查什么set回报。

+0

感谢您的评论。它现在通过在保存之前测试设置的返回值来工作。我无法从保存中删除null,或者我的回调不会触发。可能是另一个问题,但我看到了这一点: - http://stackoverflow.com/questions/6547430/backbone-js-save-with-coffeescript – Eric

+0

@Eric:对不起,我最终失去了*错*切线。你最好的选择就是使用'@model.save attrs,...',而不用单独调用'set'。给我更新的答案一读。 –

+0

谢谢!只是将其标记为已接受。 – Eric