5

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

var promise = model.save();

$.when(promise).done(function() {
   console.log('success!');
});

$.when(promise).fail(function() {
   console.log('dang');
});

但是,$.when()当通过一个 non-promise 触发时,done(),所以,在上面,如果模型无效,$.when(false).done()触发,你会得到“成功!”。

我知道我可以在 中使用successerror属性save(),但是对于我的代码,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();
}

变得很乱。你得到图片。我希望我只是在这里遗漏了一些东西。

4

2 回答 2

6

您可以覆盖 Backbone.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/

于 2013-09-20T01:45:32.393 回答
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;
};

希望能帮助到你!

于 2016-12-15T05:08:37.197 回答