1

誰かがここで私を助けることができるかどうか疑問に思います。

クライアント側にbackbone.jsを実行している単一のページがあります

サーバーはsocket.ioを実行しています。

socket.ioをサポートするために、Backbonesのデフォルトの同期をbackbone.iobindの同期に置き換えました。

保存時にサーバーからエラー応答を取得し(計画されている)、保存のエラー関数をトリガーするバックボーンモデルがありますが、クライアント側のモデルは引き続き新しい値に更新されます。私の理解では、更新する前にサーバーからの成功応答を待機する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;
}

ただし、これにより、モデルが保存されたときにモデルが変更されるのを防ぐことができます。

ハックっぽい代替手段として、validate関数内にサーバー要求を追加して、エラーをチェックし、「set」関数がモデルを変更しないようにすることができます。

于 2012-10-24T21:57:40.317 に答える
0

変更イベントが発生setしないように使用できます。silent: true

于 2012-10-24T22:04:56.807 に答える