Backbone.js 在主干中的选项视图中获取选定模型的最佳方法

Backbone.js 在主干中的选项视图中获取选定模型的最佳方法,backbone.js,marionette,Backbone.js,Marionette,考虑下面的代码。如果我在Select视图中创建一个变更事件处理程序,那么在不在option视图中分配data-cid属性的情况下,获取option视图的选定模型的最干净、最好的方法是什么。我试图将真相排除在dom之外,并以这种方式进行: var ItemView = Backbone.View.extend({ tagName: 'option', initialize:function(){ this.template= _.template($('#menu_item

考虑下面的代码。如果我在Select视图中创建一个变更事件处理程序,那么在不在option视图中分配data-cid属性的情况下,获取option视图的选定模型的最干净、最好的方法是什么。我试图将真相排除在dom之外,并以这种方式进行:

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;        
 }
});

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

解决这个问题的方法很简单,在ItemView中侦听click事件,然后在侦听器中执行类似的操作:

this.model.trigger('selected', this.model);
这将在模型中触发一个事件,并将模型本身作为参数传递(要知道已选择了wish)。在模型中触发的事件将传播到其集合

然后在CollectionView中侦听:

this.collection.on('selected', this.selectedHandler, this); 
SelectedHandler将在触发器中传递所选模型时作为参数接收该模型

更新:添加示例代码。基本上,由于DOM元素选项本身并没有作为DOM事件触发,因此我们在selectdom元素中添加了一个“plugin”来执行此操作

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'); 
 }
});

我会这样做:@AnatoliyZaslavskiy,如果事件发生在选项级别,我会同意你的看法。但是,更改事件仅发生在选择级别,而不是选项级别。因此,集合视图(一个选择视图)侦听更改事件。我如何知道选择了哪种型号?我将数据cid分配给所有选项,并通过cid获取模型,但是我不喜欢这样。它违背了使用类似于主干网的MV框架的目的。我根本不想使用dom,而是坚持使用模型。当在ItemView上发生select事件时,您引用模型:`events:{当select事件发生在DOM中时,ItemView订阅该事件并触发一个
selected
事件,或在创建视图时传入的关联模型
this.model
上设置一个
selected
属性。无需CIDs。如果设置了一个属性,则可以随时返回并在此处执行
findWhere操作。如果执行触发器,则可以按照Daniel的建议执行listenTo操作。是的,但在选项模型视图中不会触发click事件。更改事件仅在选择集合视图中触发。在选择列表中,我相信选项不会触发click事件。选择将触发更改事件。选项视图是模型视图,而select是集合视图在集合视图中,为select元素的更改事件添加一个侦听器,然后执行以下操作:this.$(“option:selected”).trigger('option_changed');在ItemView中侦听“option_changed”,我将用完整的代码示例更新我的答案。你是对的,这将有效。这比使用dom更干净。我将接受你的答案。谢谢。