正确的方式连接骨干视图

时间:2012-11-25 17:08:26

标签: backbone.js backbone-views backbone-events

I have a two views:
   1 LeftView (maximized when RightView is minimized & vice versa)
   2 RightView (containing)
      - collection of 
         - RightItemView (rendering RightItemModel)

当RightView最大化并且用户单击RightItemView时,我想最大化LeftView并根据点击的RightItemView中的数据显示内容。

连接它们的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

我建议使用Backbone.Events模块:

http://backbonejs.org/#Events

基本上,这一行就是创建事件调度程序所需的全部内容:

var dispatcher = _.clone(Backbone.Events);

然后,您的所有视图都可以使用全局调度程序触发/侦听事件。

因此,在RightItemView中,您可以在click事件中执行以下操作:

dispatcher.trigger('rightItemClick', data); // data is whatever you need the LeftView to know

然后,在LeftView的初始化函数中,您可以监听事件并调用相关函数:

dispatcher.on('rightItemClick', this.maximizeAndDisplayData);

假设你的LeftView有这样的功能:

maximizeAndDisplayData: function(data) {
    // do whatever you need to here
    // data is what you passed with the event
}

答案 1 :(得分:2)

提到的解决方案@ jordanj77绝对是达到您要求的正确方法之一。出于好奇,我想到了另一种达到同样效果的方法。我们不应该使用单独的EventDispatcher在两个视图之间进行通信,为什么我们不应该使用底层模型作为我们的EventDispatcher?让我们试着从这些方面思考。

首先,向名为boolean的{​​{1}}模型添加新的RightItem属性,并将其默认为current。每当用户选择false时,请将模型的RightItemView属性设置为true。这将触发模型上的current事件。

change:current

另一方面,var RightItem = Backbone.Model.extend({ defaults: { current: false, } }); var RightItemView = Backbone.View.extend({ events: { 'click li': 'changeCurrent' } changeCurrent: function() { this.model.set('current', true); } }); 将在创建期间交付LeftView模型的Backbone.Collection。你反正有这个实例提供RightItem不是吗?在其初始化方法中,RightView将侦听LeftView事件。事件发生时,change:current会将当前显示的模型的LeftView属性更改为false,并开始显示触发此事件的新模型。

current

这样,我们可以使用底层模型作为左视图和右视图之间的通信方式,而不是使用var LeftView = Backbone.View.extend({ initialize: function() { this.collection.on('change:current', this.render, this); }, render: function(model) { // Avoid events triggered when resetting model to false if(model.get('current') === true) { // Reset the currently displayed model if (this.model) { this.model.set('current') = false; } // Set the currently selected model to the view this.model = model; // Display the view for the current model } } }); var leftView = new LeftView({ // Use the collection that you may have given the RightView anyways collection: rightItemCollection }); 代理我们。

答案 2 :(得分:1)

@Ganeshji给出的解决方案激励我进行实时example

我为此创建了2个视图。

var RightView = Backbone.View.extend({
  el: $('.right_view'),

  template: _.template('<p>Right View</p>'),

  renderTemplate: function () {
      this.$el.html('');
      this.$el.append(this.template());  
      this.$link = this.$el.append('<a href="#" title="some data" id="left_view_max">Item to view</a>').children('#left_view_max'); 
  },

  events: {
      'click #left_view_max'    :   'maxLeftView'
  },

  maxLeftView: function () {
    //triggering the event for the leftView
    lView.trigger('displayDataInLeftView', this.$link.attr('title'));
  },

  initialize: function (options) {  
      this.renderTemplate();
  }
});

var LeftView = Backbone.View.extend({
  el: $('.left_view'),

  template: _.template('<p>Left View</p>'),

  renderTemplate: function () {
      this.$el.html('');
      this.$el.append(this.template());
  },

  displayDataInLeftView: function (data) {
    this.$el.append('<p>' + data + '</p>');
  },

  initialize: function (options) {
    //set the trigger callback
    this.on('displayDataInLeftView', this.displayDataInLeftView, this);
    this.renderTemplate(); 
  }
});

 var lView = new LeftView();
 var rView = new RightView();

希望这有帮助。