Consider the below code. If I create a change event handler in Select View, What would be the cleanest and best way to get the selected model of the option view without assigning data-cid attribute in the option view. Im trying to keep the truth out of the dom and do this Backbone way:
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;
}
});
You are right, you should NOT use anything in the DOM.
The idea to solve this is easy, at ItemView listen for the click event, then in the listener just do something like it:
this.model.trigger('selected', this.model);
This trigger an event in the model and pass as argument the model as itself(to know wish has been selected). Events triggered in models are propagated to its collection.
Then in CollectionView listen for:
this.collection.on('selected', this.selectedHandler, this);
SelectedHandler is going to receive the selected model as argument, as you passed it in the trigger.
Update: adding sample code. Basically as the DOM element option did not trigger as itself a DOM event, we add a "plugin" in the select DOM element to do it.
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');
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With