I'm trying to get my head around the correct way to organise a view when it's calling multiple collections (some which only need to be fetched initially and some which are triggered by events).
I have a collection 'Genres_collection()' which fetches a list of genres from a database:
Genres_collection:
define([
'jquery',
'underscore',
'backbone',
'models/genre_model'
],function($,_,Backbone,Genre_model){
var Genres_collection = Backbone.Collection.extend({
model: Genre_model,
url: '/api/genres',
parse: function(response){
return response;
}
})
return Genres_collection;
});
Genres_model:
define([
'jquery',
'underscore',
'backbone'
],function($,_,Backbone){
var Genre_model = Backbone.Model.extend({
defaults: {
'title': 'Untitled Track'
}
})
return Genre_model;
});
I have a view which, amoung other things, I want to fetch the genres on initialize() and then reference the collection's data in render. From my understanding, initialize is triggered only when a view is initialted (thus the name) and render() is called any number of times (ie: when an event is triggered). So, my thought is that render is used to render and 're-render' a view when actions are taken.
Therefore, I have the following view code:
Search_view:
define([
'jquery',
'underscore',
'backbone',
'collections/tracks',
'collections/genres',
'text!templates/search_view_title.html',
'text!templates/search_view.html'
],function($,_,Backbone,Tracks_collection,Genres_collection,Search_view_title_template,Search_view_template){
var Search_view = Backbone.View.extend({
el: $('#app'),
initialize: function(){
this.collection = new Tracks_collection();
this.genre_collection = new Genres_collection();
this.genre_collection.fetch();
},
search: function(searchtype){
switch(searchtype){
case 'genre':
console.log('genre changed');
this.collection.fetch({
data: {limit: 30, type:'genre',genre_id:$('#genre_select').val()}
});
break;
case 'search':
console.log('search changed');
this.collection.fetch({
data: {limit: 30, type:'search',keyword:$('#keyword').val()}
});
break;
}
},
render: function(){
// MAKE 'THIS' ACCESSIBLE
var that = this;
console.log(this.genre_collection);
var template = _.template(Search_view_template);
var template_vars = {genres: this.genre_collection};
console.log(template_vars);
var template_html = template(template_vars);
that.$el.find('#container').html(template_html);
this.collection.bind('add',function(collection){
console.log('collection has been changed');
})
}
});
return Search_view;
});
However, when I try to print the genre_collection in render() to the console or pass it to the template, I don't get the data from the collection which was fetched in initialize().
I am using requirejs and I can confirm that the initialize() and render() call is being called as I have written simpler views which execute the code fine.
In this case, your this = that
you should write
console.log(that.genre_collection)
instead of
console.log(this.genre_collection);
Add this to your initialize function
this.listenTo(this.genre_collection , 'change', this.render);
you can change your genre_collection parse nmethod so it will return your data
parse: function(response){
return response.genres
}