最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Backbone dynamically switch templates - Stack Overflow

programmeradmin1浏览0评论

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.

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.

Share Improve this question asked Sep 17, 2012 at 20:35 Gabriel SymeGabriel Syme 4454 silver badges7 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 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";
         }

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

发布评论

评论列表(0)

  1. 暂无评论