如何使用 Backbone.Model.save() promise with validation



我正在尝试使用从Backbone.model.save()返回的承诺。 实际上,根据规范,如果有效,则返回承诺,如果无效,则返回 false。 我想在将来的deferred.done()deferred.fail()调用中使用返回值,无论类型如何。 喜欢这个:

var promise = model.save();
$.when(promise).done(function() {
   console.log('success!');
});
$.when(promise).fail(function() {
   console.log('dang');
});

但是,$.when()当传递非承诺时,done(),所以,在上面,如果模型无效,$.when(false).done()触发,你会得到"成功!

我知道我可以在 save() 中使用 successerror 属性,但是对于我的代码,以后应用多个done()函数是有利的。 毕竟,这就是承诺的力量。

所以,我只剩下:

var promise = model.save();
if (promise) {
    $.when(promise).done(function() {
        console.log('success!');
    });
    $.when(promise).fail(function() {
        console.log('dang');
    });
} else {
    console.log('dang');
}

我讨厌不干。

var promise = model.save();
var fail = function() {
    console.log('dang');
};
if (promise) {
    $.when(promise).done(function() {
        console.log('success!');
    });
    $.when(promise).fail(function() {
        fail();
    });
} else {
    fail();
}

嘎嘎�� 你明白了。 我希望我只是在这里错过了一些东西。

您可以重写 Backbone.save 方法以获得所需的行为。如果原始 save 函数的返回值是布尔值(这意味着验证失败),只需返回自定义承诺并拒绝其相关的延迟。

var oldSaveFunction = Backbone.Model.prototype.save;
Backbone.Model.prototype.save = function(){
    var returnedValue = oldSaveFunction.apply(this, arguments),
        deferred = new $.Deferred();
    if(_.isBoolean(returnedValue)){
        deferred.reject();
        return deferred.promise();
    }
    return returnedValue;
}
var Person = Backbone.Model.extend({
    url : 'http://www.google.com',
    validate : function(attributes){
         if(!("name" in attributes))
             return "invalid";
    }
});
var person = new Person();
$.when(person.save()).fail(function(){
   console.log("failed"); 
});

在这把小提琴上试试看

http://jsfiddle.net/WNHXz/1/

这是对先前答案的改进,但对错误处理的支持更好。我需要它来避免吞咽错误,所以我做了:

var oldSaveFunction = Backbone.Model.prototype.save;
Backbone.Model.prototype.save = function () {
  var returnedValue = oldSaveFunction.apply(this, arguments),
    fulfiller,
    rejecter,
    pendingPromise = new Promise(function (fulfill, reject) {
      fulfiller = fulfill;
      rejecter = reject;
    });
  if (_.isBoolean(returnedValue)) {
    rejecter(this.validationError);
  } else {
    // Assuming returnedValue is a deferred
    returnedValue.then(function success() {
      fulfiller.apply(this, arguments);
    }, function failure(jqxhr, errorName, error) {
      rejecter(error);
    });
  }
  return pendingPromise;
};

希望对您有所帮助!

最新更新