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

javascript - Alternating between 2 different templates in backbone.js - Stack Overflow

programmeradmin0浏览0评论

I have 2 different templates for my model's views. Each time the models are fetched from the database, the first 3 models (#1, 2, 3) fetched from the backend will have the view created using the first template, the next 4 models (#4, 5, 6, 7) will use the second template, the next 3 models (#8, 9, 10) will use the first template and so on.

Problem: How will I introduce this alternating template using backbone.js?

JS Code

// Views

PhotoListView = Backbone.View.extend({
    el: '#photo_list',

    render: function() {
        $(this.el).html('');
        _.each(this.model.models, function(photo) {
            $(this.el).append(new PhotoListItemView({ model: photo }).render().el);
        }, this);
        return this;
    }
});

PhotoListItemView = Backbone.View.extend({
    tagNAme: 'div',
    className: 'photo_box',

    template: _.template( $('#tpl_PhotoListView').html() ),

    initialize: function() {
        this.model.bind('destroy', this.close, this);
    },

    render: function() {
        $(this.el).html( this.template( this.model.toJSON() ) );
        return this;
    },

    close: function() {
        this.unbind();
        this.remove();
    }
});

I have 2 different templates for my model's views. Each time the models are fetched from the database, the first 3 models (#1, 2, 3) fetched from the backend will have the view created using the first template, the next 4 models (#4, 5, 6, 7) will use the second template, the next 3 models (#8, 9, 10) will use the first template and so on.

Problem: How will I introduce this alternating template using backbone.js?

JS Code

// Views

PhotoListView = Backbone.View.extend({
    el: '#photo_list',

    render: function() {
        $(this.el).html('');
        _.each(this.model.models, function(photo) {
            $(this.el).append(new PhotoListItemView({ model: photo }).render().el);
        }, this);
        return this;
    }
});

PhotoListItemView = Backbone.View.extend({
    tagNAme: 'div',
    className: 'photo_box',

    template: _.template( $('#tpl_PhotoListView').html() ),

    initialize: function() {
        this.model.bind('destroy', this.close, this);
    },

    render: function() {
        $(this.el).html( this.template( this.model.toJSON() ) );
        return this;
    },

    close: function() {
        this.unbind();
        this.remove();
    }
});
Share Improve this question edited Jul 4, 2012 at 20:46 Nyxynyx asked Jul 4, 2012 at 20:30 NyxynyxNyxynyx 63.6k163 gold badges506 silver badges855 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 20

First of all, your PhotoListView is wrapping a collection so you should be using this.collection inside the view and new PhotoListView({ collection: c }) to create it. Views treat the collection option similarly to how they treat model:

constructor / initialize new View([options])

[...] There are several special options that, if passed, will be attached directly to the view: model, collection, el, id, className, tagName and attributes.

Using the right names will help prevent confusion. Also, views have some Underscore methods already mixed in so you can say this.collection.each(...) instead of _.each(this.collection.models, ...) or _(this.collection.models).each(...). You can also use this.$el instead of $(this.el).

And now on to your real problem. You can add two templates to your per-model view:

PhotoListItemView = Backbone.View.extend({
    template0: _.template($('#the-first-template-id').html()),
    template1: _.template($('#the-other-template-id').html()),
    //...
});

and an option to tell it which one to use:

initialize: function(options) {
    this.template = this['template' + options.template_number];
    //...
}

Then you just need to specify the group option from the collection view. Underscore's each passes the iteration index to the callback function as the second argument so you just need a bit of integer math to figure out which template_number to use:

this.collection.each(function(photo, i) {
    // Grouped in threes and you're alternating between two templates.
    var n = Math.floor(i / 3) % 2; 
    var v = new PhotoListItemView({ model: photo, template_number: n });
    this.$el.append(v.render().el);
}, this);
发布评论

评论列表(0)

  1. 暂无评论