0

バックボーンで非常に興味深い問題が発生しています。ビューの 1 つに次のような機能があります。

addpeople :function(){
        var authArray = _.clone(this.model.get("authorizedUsers"));
        var values = $(".add-input").val().split(",");
        values.forEach(function(value) {
            authArray.push(value);
        });
        this.model.set("authorizedUsers" , authArray);
        this.model.save();

    },

この関数は、ボタンがクリックされたときに呼び出されます。このバージョンの関数は、配列を複製しているためイベントをトリガーしますchangeが、何らかの理由でthis.model.save()呼び出されません。つまり、サーバーは PUT 要求を受信しません。ページを更新すると、モデルの古い状態に戻ります..

ただし、配列のクローンを作成せずに関数を次のように変更すると、次のようになります。

addpeople :function(){
        var authArray = this.model.get("authorizedUsers");
        var values = $(".add-input").val().split(",");
        values.forEach(function(value) {
            authArray.push(value);
        });
        this.model.set("authorizedUsers" , authArray);
        this.model.save();

    },

今回は PUT リクエストが正常に送信されましたが、変更イベントがトリガーされないため、ページは再レンダリングされません。ページを更新すると、更新されたモデルが表示されます..

this.model.save()2 番目の例で変更イベントを手動でトリガーできることはわかっていますが、最初の例で my が呼び出されない理由についてもっと知りたいです。

問題をより理解できるように、私のモデルは次のようになります。

var PostModel = Backbone.Model.extend({
    urlRoot : '/tweet',
    idAttribute: '_id',
    defaults:{
        name: '',
        comments: [],
        tags: [],
        authorizedUsers: [],
        postedBy : '',
        dateCreated: ''
    },


});

私のnode.js更新機能は次のようになります。

exports.updateTweet =  function(req,res){
  console.log("Getting called ! ")
  var update = req.body;
  var id = req.url.split("/")[2];

  Post.update({ _id: id }, { $set: { authorizedUsers: req.body.authorizedUsers }}, function (err, post) {
      if (err) return handleError(err);
  });
  res.end();

};
4

1 に答える 1

2

change2番目の例でトリガーしなかった理由は、それが同じオブジェクトであり、Backboneそれを無視するためです。したがって、changeイベントはトリガーされません。

最初のものが失敗した理由について。モデルのバリデーターはありますか? おそらく空の文字列を検証するものでしょうか?val()空の文字列を返すことができ、空の文字列のsplit()場合は戻ります[""]

また、デフォルトは関数にする必要があります。そうしないと、すべてのモデルが の同じインスタンスを持つことになりcommentsますtagsauthorizedUsers

バックボーンのドキュメントから。

JavaScript では、オブジェクトは参照によって渡されることに注意してください。そのため、オブジェクトをデフォルト値として含めると、すべてのインスタンスで共有されます。代わりに、デフォルトを関数として定義してください。

配列もオブジェクトです。

var PostModel = Backbone.Model.extend({
    urlRoot : '/tweet',
    idAttribute: '_id',
    defaults: function(){
      return {
          name: '',
          comments: [],
          tags: [],
          authorizedUsers: [],
          postedBy : '',
          dateCreated: ''
      }
  }
});

最後に、array.forEach()IE8 以前では使用できません。

于 2013-08-08T09:32:10.150 に答える