简体   繁体   English

如何从Backbone.js中的集合中的另一个模型触发模型更新?

[英]How to trigger a model update from another model in a collection in Backbone.js?

Update: Here is a working demo of the project I was working on: http://www.newedenfaces.com 更新:这是我正在进行的项目的工作演示: http//www.newedenfaces.com

I have two views: PeopleView that holds 2 thumbnails (collection) and PersonView - each thumbnail itself (model). 我有两个视图: PeopleView包含2个缩略图(集合)和PersonView - 每个缩略图本身(模型)。

This is basically a Facemash clone where you have two images side-by-side. 这基本上是一个Facemash克隆,你有两个并排的图像。 If one person wins the game, another one loses the game. 如果一个人赢了比赛,另一个人输掉比赛。

In order to update wins count , it's easy, just add this to the PersonView : 为了更新wins count ,这很简单,只需将其添加到PersonView

// Model View
events: {
    'click img': 'winner'
},
winner: function() {
    this.model.set('wins', this.model.get('wins') + 1);
    this.model.save();
}

But how do I update the other model by incrementing the losses count? 但是如何通过增加损失计数来更新其他模型 Or should I be doing this type of logic at the collection level rather than on an individual model? 或者我应该在集合级别而不是在单个模型上执行此类逻辑?

Update 更新

Until I find an elegant solution I've managed to solve this problem using this hack: 直到我找到一个优雅的解决方案,我已设法使用此hack解决此问题:

// Collection View
initialize: function() {
    this.collection.on('change:wins', this.updateLosses, this);
  },

  updateLosses: function(model) {
    var winnerIndex = this.collection.indexOf(model);
    var otherModel = this.collection.at(Math.abs(1 - winnerIndex));
    otherModel.set('losses', otherModel.get('losses') + 1);
    otherModel.save();
    this.render();
  },

My PersonView still handles the update of wins count. 我的PersonView仍然处理wins count的更新。 However the PeopleView collection view listens for the event when wins count is updated. 但是,当更新wins count时, PeopleView集合视图将侦听事件。 When that happens it takes that model and gets its index position. 当发生这种情况时,它会采用该模型并获得其索引位置。 Since I only have 2 views / 2 models, the other model must have been a "loser". 由于我只有2个视图/ 2个模型,所以另一个模型必定是“失败者”。 You get the index of the other model via Math.abs(1 - winnerIndex) , and the only things that you have to do is update its losses count . 您可以通过Math.abs(1 - winnerIndex)获得其他模型的索引,并且您需要做的唯一事情就是更新其损失计数

Note : I have just started learning Backbone, so this is my first project using it. 注意 :我刚刚开始学习Backbone,所以这是我第一个使用它的项目。 I really hope there is a better way to do this. 我真的希望有更好的方法来做到这一点。 If you know, post an answer so I could accept and close this question. 如果你知道,发表一个答案,我就可以接受并关闭这个问题了。

Similar to @pvnarula's answer, you can use Backbone's built in Event module to create an event dispatcher that model views are bound to. 与@ pvnarula的答案类似,您可以使用Backbone的内置Event模块来创建模型视图绑定的事件调度程序。

// Define an event dispatcher/handler
var dispatcher = _.extend({}, Backbone.Events);

// Model View
initialize: {
    this.listenTo(dispatcher, 'game:over', this.updateCounts);
}

events: {
    'click img': 'winner'
},

winner: function() {
    // just trigger the custom event and let each view figure out how to respond.
    // also pass along the id of the winning model
    dispatcher.trigger('game:over', this.model.id)
},

updateCounts: function(winnerId) {
    if (this.model.id === winnerId) {
        this.model.set('wins', this.model.get('wins') + 1); 
    } else {
        this.model.set('losses', this.model.get('losses') + 1);
    }
    this.model.save();
}

Also worth checking out this article for more about Backbone Events: http://lostechies.com/derickbailey/2012/04/03/revisiting-the-backbone-event-aggregator-lessons-learned/ 另外值得查看本文以了解有关Backbone Events的更多信息: http//lostechies.com/derickbailey/2012/04/03/revisiting-the-backbone-event-aggregator-lessons-learned/

Actually you want to access other view from your current view and update it accordingly. 实际上,您希望从当前视图访问其他视图并相应地进行更新。 I am afraid you need to create your own observer pattern. 我担心你需要创建自己的观察者模式。 I mean publish and subscribe. 我的意思是发布和订阅。

var otherView = Backbone.View.extend({
   initialize : function(){
       observer.subscribe('your_custom_event');
   },
   your_custom_event : function(){
      //update the view and it's model
   }
});

winner: function() {
    this.model.set('wins', this.model.get('wins') + 1);
    this.model.save({wins: this.model.get('wins')});
    observer.publish('your_custom_event', arguments);
}

You can get very good available patterns from the web easily those are compatible with backbone. 您可以从Web上轻松获得与骨干兼容的非常好的可用模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM