发布事件数据时如何定位正确的集合以使用新数据重置?

How to target the correct collection to reset with new data when publishing event data?

我已经设置了 websockets 并使用事件来发布从服务器传输的任何数据。但是我有一个问题,当我渲染多个集合视图时,每个视图都会在新数据发布时更新,因为现在我监听集合中的事件然后用新数据重置集合,理想情况下我只想更新 1 集合这些数据是用来做什么的,但我不确定我必须做什么?如果我发送带有响应的 ID,我是否能够找到正确的集合?

示例 JS

App.C.StocksCollection = Backbone.Collection.extend({

    model: App.M.StockModel,

    initialize: function() {
        this.listenTo(Backbone.Events, 'collection:data:published', this.setCollection, this);
    },

    setCollection: function(response) {
        // Should I have an id or something in the response id to pick the correct collection? Not sure?
        this.reset(response, {
            parse: true
        });
    },
});

setTimeout(function() {
    Backbone.Events.trigger('collection:data:published', updatedResponse);
}, 4000);

JSFiddle http://jsfiddle.net/kyllle/xrn89sa1/

是的,附加的 id 字段可用于确定应重置哪个集合。在下面的代码段中搜索 cfa 以查看添加的代码。

console.clear();
// cfa: JSON format changed to include myId
var stockDataOne = [{
  myId: 1,
  list: [{
    symbol: "GM",
    open: 38.87
  }, {
    symbol: "GE",
    open: 25.40
  }, {
    symbol: "MCD",
    open: 97.05
  }]
}];
var stockDataTwo = [{
  myId: 2,
  list: [{
    symbol: "UAL",
    open: 69.45
  }, {
    symbol: "WMT",
    open: 83.24
  }, {
    symbol: "AAL",
    open: 55.76
  }, ]
}];
var updatedResponse = [{
  myId: 1,
  list: [{
    symbol: "LLY",
    open: 76.12
  }, {
    symbol: "JPM",
    open: 61.75
  }, {
    symbol: "BAC",
    open: 15.84
  }, {
    symbol: "BA",
    open: 154.50
  }]
}];

var App = {
  M: {},
  V: {},
  C: {},

  start: function() {

    _.extend(this, Backbone.Events);

    // Stocks One.
    var stocksOne = new App.C.StocksCollection(stockDataOne[0].list, {
      myId: stockDataOne[0].myId // cfa: pass myId to collection
    });
    var stocksViewOne = new App.V.StocksCollectionView({
      collection: stocksOne
    });

    // Stocks Two.
    var stocksTwo = new App.C.StocksCollection(stockDataTwo[0].list, {
      myId: stockDataTwo[0].myId
    });
    var stocksViewTwo = new App.V.StocksCollectionView({
      collection: stocksTwo
    });

    // Append.
    $('.js-one').append(stocksViewOne.render().el);
    $('.js-two').append(stocksViewTwo.render().el);


    // Example socket output with new data for Stock View One 
    setTimeout(function() {
      Backbone.Events.trigger('collection:data:published', updatedResponse);
    }, 4000);
  }
};

// Classes
App.M.StockModel = Backbone.Model.extend();

App.C.StocksCollection = Backbone.Collection.extend({
  myId: null,

  model: App.M.StockModel,

  initialize: function(models, options /* cfa: options parameter has the myId value */) {
    this.myId = options.myId;
    this.listenTo(Backbone.Events, 'collection:data:published', this.setCollection, this);
  },

  setCollection: function(response) {
    if (this.myId == response[0].myId) {//cfa: if myIdd from response matches myId of the collection then do a reset
      response = response[0].list;
      this.reset(response, {
        parse: true
      });
    }
  },
});

App.V.StocksCollectionView = Backbone.View.extend({

  tagName: 'ul',

  isRendered: false,

  initialize: function(options) {
    this.fragment = document.createDocumentFragment();
    this.listenTo(this.collection, 'reset', this.render, this);
  },

  render: function() {
    this.collection.forEach(this.addStock, this);

    this.$el.html(this.fragment);

    return this;
  },

  addStock: function(stock) {

    var stockView = new App.V.StockView({
      model: stock
    });
    this.fragment.appendChild(stockView.render().el);
  }
});

App.V.StockView = Backbone.View.extend({

  tagName: 'li',

  template: Handlebars.compile($('.tmpl-stock').html()),

  render: function() {
    this.$el.html(this.template(this.model.toJSON()));

    return this;
  }
});

App.start();
* {
  -webkit-font-smoothing: antialiased;
}
body {
  padding: 5%;
}
.cols {
  display: flex;
  justify-content: space-around;
}
li {
  margin: 10px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

<div class="cols">
  <div class="js-one">
    <b>Stocks 1</b>
  </div>
  <div class="js-two">
    <b>Stocks 2</b>
  </div>
</div>

<script type="text/x-handlebars-template" class="tmpl-stock">
  <p>{{symbol}}</p>
  <p>{{open}}</p>
</script>