Backbone Validate在验证失败时发送请求

时间:2012-06-11 15:22:07

标签: validation backbone.js

根据有关验证的主干文档,它指出:

  

如果validate返回错误,则设置和保存将不会继续,并且   模型属性不会被修改。

因此,如果验证失败,我应该永远不会运行设置或保存的方式。但这不是我得到的结果。即使验证失败,它仍然会发送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

1 个答案:

答案 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模型时,验证主要由set code 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最终会使用some attributes来调用setset会调用validate。演示:http://jsfiddle.net/ambiguous/HHQ2N/1/

但是,如果你说:

@model.save null, ...

null will 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. Backbone对save(null, ...)的参数处理可能会更好,但我不知道是否值得努力处理一种奇怪的方式来调用它。
  4. 您应该将set / save对合并为save或检查set返回的内容。