【问题标题】:Best way to get selected model in option view in Backbone在 Backbone 的选项视图中获取选定模型的最佳方法
【发布时间】:2014-08-09 05:10:12
【问题描述】:

考虑下面的代码。如果我在选择视图中创建一个更改事件处理程序,那么在不分配选项视图中的 data-cid 属性的情况下,获取选项视图的选定模型的最简洁和最佳方法是什么。我试图让真相远离 dom,并以这种 Backbone 方式:

var ItemView = Backbone.View.extend({
tagName: 'option',
initialize:function(){        
    this.template= _.template($('#menu_item_view').html());    
},    
render:function(){        
    this.$el.html(this.template(this.model.toJSON()));        
    return this;        
}
});

var CollectionView = Backbone.View.extend({
  tagName: 'select',
  initialize:function(){        
    this.collection = new ItemCollection();            
    this.collection.on('sync',this.render,this);            
    this.collection.fetch();
 },    
 render:function(){        
    this.$el.html(this.collection.map(function( item ){            
        return new ItemView ({model:item}).render().el;        
    },this);      
    return this;        
 }
});

【问题讨论】:

  • @AnatoliyZaslavskiy,如果事件发生在期权级别,我会同意你的看法。但是,更改事件仅发生在 Select 级别,而不发生在 Option 级别。所以集合视图,它是一个选择视图,会监听更改事件。我怎么知道选择了哪个型号?我将 data-cid 分配给所有选项并通过 cid 获取模型,但是我不喜欢那样。它违背了使用像 Backbone 这样的 MV 框架的目的。我根本不想用dom,坚持model。
  • When the select event happens on the ItemView you reference the model: `events: {
  • 当 select 事件在 DOM 中发生时,ItemView 订阅它并触发 selected 事件或在创建视图时传入的关联模型 this.model 上设置 selected 属性.无需 CID。如果您设置了一个属性,您可以随时返回并在集合上执行findWhere。如果你做一个触发器,你可以像丹尼尔建议的那样做一个listenTo。
  • 是的,但是点击事件永远不会在选项模型视图中触发。更改事件仅在选择集合视图中触发。 jsfiddle.net/7cfjznjn

标签: backbone.js marionette


【解决方案1】:

你是对的,你不应该在 DOM 中使用任何东西。

解决这个问题的想法很简单,在 ItemView 监听点击事件,然后在监听器中做类似的事情:

this.model.trigger('selected', this.model);

这会在模型中触发一个事件,并将模型作为参数传递给模型本身(以知道希望已被选中)。在模型中触发的事件被传播到它的集合中。

然后在 CollectionView 中监听:

this.collection.on('selected', this.selectedHandler, this); 

SelectedHandler 将接收所选模型作为参数,就像您在触发器中传递它一样。

更新:添加示例代码。基本上由于 DOM 元素选项本身不会触发 DOM 事件,因此我们在 select DOM 元素中添加一个“插件”来执行此操作。

var ItemView = Backbone.View.extend({
  tagName: 'option',
  events : {
    'option_changed' : 'optionChangedHandler'
  },
  initialize:function(){        
    this.template= _.template($('#menu_item_view').html());    
  },    
  render:function(){        
    this.$el.html(this.template(this.model.toJSON()));        
    return this;        
  },
  optionChangedHandler : function(){
    this.model.trigger('selected', this.model);
  }
});

var CollectionView = Backbone.View.extend({
  tagName: 'select',
  events : {
    'change' : 'changeHandler'
  },
  initialize:function(){        
    this.collection = new ItemCollection();            
    this.collection.on('sync',this.render,this);    
    this.collection.on('selected',this.selectedModel, this);            
    this.collection.fetch();
 },    
 render:function(){        
    this.$el.html(this.collection.map(function( item ){            
        return new ItemView ({model:item}).render().el;        
    },this);      
    return this;        
 },
 selectedModel : function(model){
    console.log('it is magic: ', model);
 },
 changeHandler : function(){
   this.$("option:selected").trigger('option_changed'); 
 }
});

【讨论】:

  • 在选择列表中,我不相信选项会触发点击事件。 jsfiddle.net/7cfjznjn 选择将触发更改事件。 option view是model view,select是collection view
  • 在集合视图中,为 select 元素的 change 事件添加一个侦听器,然后执行以下操作: this.$("option:selected").trigger('option_changed');在 ItemView 中监听“option_changed”,我将使用完整的代码示例更新我的答案。
  • 你说得对,它会起作用。这比使用 dom 更干净。我会接受你的回答。谢谢。
猜你喜欢
  • 2015-01-31
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多