Backbone.js客户端模型在服务器端错误上保存问题

时间:2012-10-24 21:01:20

标签: javascript node.js backbone.js socket.io

想知道是否有人可以帮助我。

我在客户端有一个页面运行backbone.js

服务器正在运行socket.io。

我用backbone.iobind同步替换了Backbones默认同步以支持socket.io。

我有一个骨干模型,在保存时从服务器获取错误响应(计划中),并触发保存的错误功能但是我的客户端模型仍然更新为新值。我已经包括wait:true,根据我的理解,在更新之前等待服务器的成功响应,但这对我来说不会发生。

服务器端socket.io代码

io.sockets.on('connection', function (socket) {
  socket.on('test:create', function (data, callback) {
    //err - used to fake an error for testing purposes
    var err = true;
    if (err) {
      // error
      callback('serv error');
    } else {
      // success
      // The callback accepts two parameters: error and model. If no error has occurred, send null for error.
      callback(null, data);
    }
  });

客户端代码

  //HTML Code
  //<div id="callBtns">
    //<button id="runTest">Create</button>
  //</div>


  var CommunicationType = Backbone.Model.extend({
    defaults: {
      runTest: 'default'
    },
    urlRoot : '/test',
    validate: function(attrs) {
            //return 'error';    
    }
  }); 

  var BasicView = Backbone.View.extend({    
    el: $('#callBtns'), 

    initialize: function(){
      _.bindAll(this); 
    },

    events: {
    "click #runTest": "runTestFn"
    },

    runTestFn: function() {

      //causing the issue?
      communicationType.set({runTest: 'value from set'});     

      communicationType.save({},{
        success:function(model, serverResponse){
          console.log('Success');
          console.log(serverResponse);
        },
        error:function(model, serverResponse){
          console.log('Error');
          console.log(serverResponse);
          console.log(JSON.stringify(communicationType));
        },
        wait: true
      });
    }

  });

  var communicationType = new CommunicationType(); 
  var basicView = new BasicView();

我注意到这个问题看起来是因为我正在使用set来直接更新我的模型 communicationType.set({runTest:'value from set' });

如果我在保存之前没有设置任何值,并将值直接传递给save,就像在下面的代码中一样,它可以正常工作,例如

communicationType.save({runTest: 'value from save'},{
            success:function(....

然而,这意味着我不能设置任何新值/更新我的模型而不通过保存功能:/

所以我的问题是,如何才能正常工作(如果出现服务器端错误,请让客户端模型不更新),同时仍能使用set?

任何答案都非常感谢!非常感谢

2 个答案:

答案 0 :(得分:2)

这是无法做到的,因为你的模型在发出请求之前无法知道它的数据是否有效(在这种情况下是model.save)。

如果要在传递无效值时阻止Backbone.Model.set工作,则必须更新模型的“验证”功能以检查错误。

鉴于以下验证功能:

validate: function(attrs) {
    this.errors = [];
    if (attrs.runTest === 'wrong_value') {
      this.errors.push('error message');
    }
    return _.any(this.errors) ? this.errors : null;
}
在您的CommunicationType模型上

。在BasicView中运行此代码:

communicationType.set({runTest: 'wrong_value'});

不会改变模型。

您还可以使用validate函数通过返回errors数组并检查它来检查服务器端错误:

validate: function(attrs) {
    this.errors = [];
    if (attrs.runTest === 'wrong_value') { // client side check
      this.errors.push('error message');
    }
    if (attrs.errors && attrs.errors.length > 0) { // server side check
        for (var key in attrs.errors) {
            this.errors.push(attrs.errors[key]);
        }
    }
    return _.any(this.errors) ? this.errors : null;
}

但这只会阻止在保存时更改模型。

作为一种黑客替代方案,您可以在validate函数中添加服务器请求,以检查错误并防止“set”函数更改模型。

答案 1 :(得分:0)

您可以将setsilent: true一起使用,这样就不会触发更改事件。