The context here is Backbone but it's a general question about dynamically creating javascript objects.
I would like to pass the name of a View ('ViewX') to be created, to a function which can then create the new ViewX()
How could I do this?
In my Backbone View I want to create a subView, the type of which depends on the Model I have used for the current View. At the moment I have an if-else structure (See Approach #1 in the example) which works, but is clunky and will be more clunky in future when I have more Model types.
I have tried some alternatives, including evaluation via the Function constructor (Approach #2), which gives 'string is not a function' error.
In Approach #3, the View module I am passing as a parameter is not available in the current View's this
namespace (I am using requirejs).
renderContentList: function() {
var self = this;
// Approach #1
var setSidebarListCollectionView = function(type) {
if (type === 'tags') {
self.sidebarListCollectionView = new TagSidebarListCollectionView({
collection: self.collection,
tagCollection: self.tagCollection
});
} else {
self.sidebarListCollectionView = new CardSidebarListCollectionView({
collection: self.collection,
tagCollection: self.tagCollection
});
}
};
/*
// Approach #2
var setSidebarListCollectionView = new Function('type', 'coll', 'tagColl', 'return new type({collection: coll, tagCollection: tagColl});');
// Approach #3
var setSidebarListCollectionView = function(type) {
return new self[type]({
collection: self.collection,
tagCollection: self.tagCollection
});
};
*/
// reset it every time
if (this.sidebarListCollectionView) {
this.sidebarListCollectionView.remove();
}
if (this.model.get('activeSubTab') === 'tags') {
// Approach #1
setSidebarListCollectionView('tags');
// Approach #2
// this.sidebarListCollectionView = setSidebarListCollectionView('TagSidebarListCollectionView', this.collection, this.tagCollection);
// Approach #3
// this.sidebarListCollectionView = setSidebarListCollectionView('TagSidebarListCollectionView');
} else {
// Approach #1
setSidebarListCollectionView('cards');
// Approach #2
// this.sidebarListCollectionView = setSidebarListCollectionView('CardSidebarListCollectionView', this.collection, this.tagCollection);
// Approach #3
// this.sidebarListCollectionView = setSidebarListCollectionView('CardSidebarListCollectionView');
}
// render the list of content title links.
this.$el.find('#content-manager-list-content').append(this.sidebarListCollectionView.render().el);
},