在Backbone的选项视图中获取所选模型的最佳方法

Ale*_*man 5 backbone.js marionette

请考虑以下代码.如果我在选择视图中创建更改事件处理程序,那么获取选项视图的所选模型的最简洁和最好的方法是什么,而不在选项视图中指定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;        
 }
});
Run Code Online (Sandbox Code Playgroud)

Dan*_*nda 6

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

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

this.model.trigger('selected', this.model);
Run Code Online (Sandbox Code Playgroud)

这会触发模型中的事件,并将模型作为参数传递给自身(以了解已选择的愿望).模型中触发的事件将传播到其集合中.

然后在CollectionView中听取:

this.collection.on('selected', this.selectedHandler, this); 
Run Code Online (Sandbox Code Playgroud)

当您在触发器中传递时,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'); 
 }
});
Run Code Online (Sandbox Code Playgroud)