【问题标题】:Prevent Backbone set validates after save保存后防止主干集验证
【发布时间】:2014-08-02 00:39:31
【问题描述】:

我正在尝试对涉及到服务器的 ajax 调用的 Backbone 模型进行客户端验证,以确定新条目是否与现有条目重复(通过匹配标题来确定)。步骤如下

  1. 检查模型是否是新的。
  2. 如果是新的,从 validate() 获取 AJAX 以查看模型是否已经存在(按标题)。
  3. 如果响应 = 重复设置状态无效,如果不继续,则继续 save()

我遇到的问题是 Backbone 正在执行以下操作。

  1. 保存()
  2. validate() : GET 返回不重复
  3. 验证通过,set()
  4. validate() : GET 返回重复

我的问题是关于如何防止第二个 validate() 在设置上触发,因为它触发了另一个 GET 请求,即使技术上我“完成”保存,我也会收到错误响应。

为了简短起见,这里是验证和保存调用

List = Backbone.Model.extend({

idAttribute: "_id",

urlRoot: '/api/lists',
...

validate: function(attrs) {
    // if we are editing don't bother with this (for now)
    if (this.isNew()) {

        // see if this title already exists
        var result = '';

        $.ajax({
            url: "/api/lists/" + this.generateTitleKey(attrs.title),
            type: "GET",
            async: false,
            success: function(data){
                result = data;
            }
        });

        if(result.length > 0) {
                return {
                    field: "title",
                    errMsg: "You already have this list"
                };
        }
    }
}
});


ListView = Backbone.View.extend({

...

save: function() {

    var _self = this;
    var fields = {
        title: _self.$el.find('input[name="new-list-name"]').val()
    }

    _self.resetErrors();

    _self.model.save(fields, {
        wait: true,
        silent: true,
        success: function(model, res) {
            if(res.err) {
                // add UI error
            } else {
                new app.View({ model: _self.model });
                _self.close();
            }
        },
        error: function(model, res) {
            console.log('inside error');
        }
    })
}
});

app.post('/api/lists', function(req, res){

var list = new ListModel({
    titleKey: generateTitleKey(req.body.title),
    title: req.body.title
});

return list.save(function(err){
    if(!err) {
        return res.send(list);
    } else {
        return res.status(409).send(JSON.stringify({
            err: true,
            errSrc: "list",
            errType: "insert",
            errMsg: "That's already a list!"
        }));
    }
});
});

silent: true 似乎对我不起作用,save() 和 set() 都触发了 validate()。

我知道有很多方法可以对验证进行错误处理,但我特意尝试使用主干模型具有的本机验证方法,并且在我尝试将它与 ajax 调用一起使用之前,它一直运行良好.我离这里很近,我可以尝到它。

【问题讨论】:

    标签: ajax validation backbone.js save set


    【解决方案1】:

    您可以使用model.set('something', true, { validate: false }); 告诉模型不要验证集合。仅供参考,如果需要,您可以在 .save 选项哈希中执行相同操作。

    你到底在设置什么?通常,服务器响应是您要保存在客户端模型上的属性,因此也许您可以返回所需的内容并避免调用 set。

    【讨论】:

    • 如果我通过 validate: false 到 save() 它不会在推送到服务器之前跳过初始验证吗?事情是我自己没有打电话。 Save() 在成功存储到服务器后调用 Set()。我什至没有直接调用 Set(),我只调用了 save(fields, { opts })。当每个被触发时,我将主干 set() 和 save() 覆盖到控制台日志,并且当 save() 成功时自动调用 Set()。
    • 嗯,好的。是的 save 将调用预期的 set - 您应该返回模型应该在其自身上设置的所有属性。再次查看您的代码表明问题是if (this.isNew()) { 无法正常工作,第二次它不应该是新的 - 我的猜测是您在保存模型时没有返回 ID 或者 id 没有被映射(如果它不称为“id”,则需要告诉 Backbone)。
    • 好,好的,所以至少我在 save() -> set() 流程中是正确的。我更新了我的代码以显示我将模型id 分配给什么以及我的服务器返回什么(node.js、mongoose)。如果 API 的返回语法看起来正确,请告诉我,我会回去调试里面的内容。我想确保我正在执行 API 保存并正确返回变量。
    • 很好奇。如果我尝试 set() 模型(具有有效 ID)并且 validate() 发生在允许 set() 之前,那么 isNew() 在技术上是否仍然正确,因为 _id 尚未分配?跨度>
    【解决方案2】:

    Dominic Tobias 引导我找到了正确的答案。

    isNew() 不能作为检查,因为在服务器的响应中,模型在设置之前已经过验证,因此在验证后 save() 集时 isNew() 在技术上仍然是正确的。我将 validate() 中的检查更改为 if(attrs._id),一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      相关资源
      最近更新 更多