1

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

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

服务器正在运行 socket.io。

我已将 Backbones 默认同步替换为主干.iobind 同步以支持 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'});

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

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

但是,这意味着如果不通过保存功能,我将无法设置任何新值/更新我的模型:/

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

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

4

2 回答 2

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 函数通过返回错误数组并检查它来检查服务器端错误:

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;
}

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

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

于 2012-10-24T21:57:40.317 回答
0

您可以使用setwithsilent: true所以它不会触发更改事件。

于 2012-10-24T22:04:56.807 回答