如果一个模型验证失败,则停止收集的主干验证

时间:2014-12-17 16:33:16

标签: backbone.js

如果一个模型未通过验证,是否有办法停止colelction的骨干验证?目前,代码执行此操作(取自Backbone.js 1.1.0):

for (i = 0, l = models.length; i < l; i++) {
    attrs = models[i];
    if (attrs instanceof Model) {
        id = model = attrs;
    } else {
        id = attrs[targetModel.prototype.idAttribute];
    }

    // If a duplicate is found, prevent it from being added and
    // optionally merge it into the existing model.
    if (existing = this.get(id)) {
        if (remove) modelMap[existing.cid] = true;
        if (merge) {
            attrs = attrs === model ? model.attributes : attrs;
            if (options.parse) attrs = existing.parse(attrs, options);
            existing.set(attrs, options);
            if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
        }
        models[i] = existing;

        // If this is a new, valid model, push it to the `toAdd` list.
    } else if (add) {
        model = models[i] = this._prepareModel(attrs, options);
        if (!model) continue;
        toAdd.push(model);

        // Listen to added models' events, and index models for lookup by
        // `id` and by `cid`.
        model.on('all', this._onModelEvent, this);
        this._byId[model.cid] = model;
        if (model.id != null) this._byId[model.id] = model;
    }
    if (order) order.push(existing || model);
}

因此,如果_prepareModel返回false,那么如果模型无效,它将跳到下一个模型并尝试验证并添加它。

如果其中一个模型未通过验证,我想停止吗?我正在开发的应用程序是一个平板电脑应用程序,从服务器返回数千个模型(当然代表JSON),所以如果第一个模型未通过验证,我不希望所有其他模型也被验证,如整个系列将受到保护。

我有什么想法可以做到这一点吗?

1 个答案:

答案 0 :(得分:0)

我会覆盖你馆藏的fetch方法。像这样:

youCollection.fetch = function(options) {
  options = options ? _.clone(options) : {};
  if (options.parse === void 0) options.parse = true;
  var success = options.success;
  var collection = this;
  options.success = function(resp) {
    var method = options.reset ? 'reset' : 'set';
    if (success) {
      if (success(collection, resp, options))
        collection[method](resp, options);
    } else
        collection[method](resp, options);
    collection.trigger('sync', collection, resp, options);
  };
  wrapError(this, options);
  return this.sync('read', this, options);
}

这是发生了什么。专注于以options.success =开头的行。当您的服务器返回所请求的模型时,触发器会调用由options.success定义的函数作为参数传递模型。在原始代码中,options.success如下所示:

 options.success = function(resp) {
    var method = options.reset ? 'reset' : 'set';
    collection[method](resp, options);
    if (success) success(collection, resp, options);
    collection.trigger('sync', collection, resp, options);
  };

这里重要的是collection[method](resp, options);调用在调用fetch的collection上设置。只有这样你才能选择调用自己的回调。调用collection.set后,模型上的验证循环开始,我们无能为力。

我们希望改变这种状况。我们想首先调用我们自己的成功函数。如果每个for loop,此函数将运行model.isValid()检查,并在失败时立即返回false。如果一个失败,我们永远不会达到collection[method](resp, options);并且永远不会发生。

要在success来电中设置fetch功能,只需在传递到fetch

的选项中删除对它的引用即可
yourCollection.fetch({ success: checkValidate });

我还会指向Backbone.validate,以便您可以阅读模型无效时触发的“调用”触发器。这样你就可以处理另一个提取或其他任何事情。