Miguel Cabrera Miguel Cabrera - 2 months ago 8
Javascript Question

how to only render one view inside of the epoxy render function

I'm working on a Backbone, Marionette, Epoxy, Underscore program and I'm having trouble rendering a single view that is nested inside of a view constructor in the Render() function. There are 3 other views inside of this function, but when the constructor is called I want to be able to render only the CustomizationView.

Is there a way that I can do that?

This is the code that calls the view constructor for SettingsView and renders it inside of CustomerView

render:function(){
//renders all of the settings from the settings inclusion variable
var data = this.viewModel.toJSON();
data.customer = this.model.toJSON();
this.$el.html(_.template(tmpl, data, {variable:'data'}));
this.ui_settings = new settings.SettingsView({
el: this.$('#vc-customer-settings'),
model: this.model.get("_Settings")
});
this.applyBindings();
}


This is the render function that is inside of the settingsView constructor. I can comment out the views that I don't want to see in the CustomerView and it works, but then it breaks the rest of the program. Is there any way that I can just get the the CustomizationView model when calling the settings.SettingsView constructor? I obviously want to keep the SettingsView because it contains a lot of code that I need alongside the CustomizationView.

render:function(){
this.$el.html(_.template(other_settings, {}, {variable:'args'}));

this.ui_messages = new LIB.MessageCollectionView({
el:this.$('.messages ul'),
collection:this.model.get("_Messages"),
parent: this
});

this.ui_customizations = new LIB.CustomizationCollectionView({
el:this.$('.other-settings ul'),
collection:this.model.get("_Customizations")
});

this.ui_increments = new LIB.IncrementCollectionView({
el:this.$('.increments ul'),
collection:this.model.get("_Increments")
});

Answer

I fixed the problem. I simply created a new constructor called adminRender() and then inside of that I called the CustomizationView constructor using a new html template for this.$el.html(_.template()). Then when the SettingsView class object is instantiated inside of the CustomerView I tested for the current working directory and created a ternary statement that calls the appropriate render function. It looks like this:

            adminRender:function(){
                this.$el.html(_.template(other_settings, {}, {variable: 'args'}));

                this.ui_customizations = new LIB.CustomizationCollectionView({
                    el:this.$('.other-settings ul'),
                    collection:this.model.get("_Customizations")
                });



                this.listenToOnce(this.model, 'change:Keymap', this.initKeymap);
                this.listenTo(this.model, 'keypressed', _.bind(this.replaceButton, this));
            },
            userRender:function(){
                this.$el.html(_.template(tmpl, {}, {variable:'args'}));

                this.ui_messages = new LIB.MessageCollectionView({
                    el:this.$('.messages ul'),
                    collection:this.model.get("_Messages"),
                    parent: this
                });
                this.ui_customizations = new LIB.CustomizationCollectionView({
                    el:this.$('.other-settings ul'),
                    collection:this.model.get("_Customizations")
                });

                this.ui_increments = new LIB.IncrementCollectionView({
                    el:this.$('.increments ul'),
                    collection:this.model.get("_Increments")
                });

Then in the SettingsView constructor I would call the appropriate render function like this:

            var pathName = window.location.pathname;
            var pathName = "/admin/customers/new" ? view.adminRender() : view.userRender();

and now it works!!! Yay :)