Backbone dynamically switch templates
Asked Answered
H

2

12

I need to initially set a Backbone view's template based on whether the date a user has selected is in the past or future as well as switch it later when it's collection changes pulling data from a different date. How do I do this? I thought I would be able to set the template to a function that returns the correct selector string based on whether I'm in the past or not, but this doesn't work.

pR.views.ScheduleJobView = Backbone.Marionette.ItemView.extend({
    tagName: "tr",
    // NEED A WAY TO SWITCH THIS TOO
    template: "#schedule-job-template"
});


pR.views.ScheduleJobsView = Backbone.Marionette.CompositeView.extend({
    // DOESN'T WORK
    template: function () {
        if (this.isPast)
            return "#schedule-jobs-past-template";
        else
            return "#schedule-jobs-template";
    },      itemView: pR.views.ScheduleJobView,

    itemView: pR.views.ScheduleJobView,
    itemViewContainer: "tbody",

    // Defaults for the model's url
    baseUrl: "/schedules/day/",
    baseApiUrl: "/api/schedule/day/",
    // Empty object to store url parameters
    urlParameters: {},

    initialize: function () {
        pR.vent.bindTo("change:parameters", this.changeUrl, this);
        this.model.url = this.baseApiUrl;
    },

    onRender: function () {
        console.log("Rendering Jobs View");
    },

    // Change the main model's url
    changeUrl: function (parameters) {
        // merge new parameters with old ones
        this.urlParameters = _.extend(this.urlParameters, parameters);

        var url = "";
        var apiUrl = this.baseApiUrl;

        _.each(this.urlParameters, function (value, parameter) {
            // Add each parameter segment to the url
            url = url + parameter + '/' + value + '/';
            apiUrl = apiUrl + parameter + '/' + value + '/';
        });

        this.model.url = apiUrl;
        console.log("Updated CurrentDay model url to " + apiUrl);
        this.model.fetch();

        console.log("Navigating to " + url);
        pR.routers.appRouter.navigate(url);
    },

    // Check if we are in the past
    isPast: function () {
        var year = this.urlParameters.year;
        var month = this.urlParameters.month;
        var day = this.urlParameters.day;
        var selectedDate = Date(year, month, day);

        if (selectedDate < Date()){
            return true;
        } else {
            return false;
        }
    }
});

Note that I'm using Marionette's composite views here, too, so I need a way to change the itemView's template based on the timeframe as well. I'm definitely open to approaching this differently if my basic strategy is poorly thought out.

Haystack answered 17/9, 2012 at 20:35 Comment(0)
G
17

You are setting this.template to a method, and Marionette is looking for a string value.

You can probably get away with using the same logic but putting it into your initialize method.

pR.views.ScheduleJobsView = Backbone.Marionette.CompositeView.extend({
    template: null,
    [ ... ]
    initialize: function () {
         if (this.isPast) {
             this.template = "#schedule-jobs-past-template";
         } else {
             this.template = "#schedule-jobs-template";
         }
Grindstone answered 17/9, 2012 at 22:56 Comment(3)
Cool, that works! I thought I had tried something like this, but I must have done something wrong. Do you have any way to set the itemView's template based on the timeframe too?Haystack
Just a note: Marionette used to accept a function for a template that would return a dynamic selector. Now the function it accepts is used as the compiled template function.Tachycardia
it worked for me. You could also do this in another function and call this.render() afterwards and it'll switch the template. Fun stuff!Congruency
M
2

There is a function called getTemplate built in for this, I know I saw it in the documentation (That's what I was googling for)

Marionette template switching documentation

Moffit answered 31/7, 2014 at 11:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.