简体   繁体   中英

Backbone.Marionette view with subviews

What is the apropriate aproach to setup a view in a Backbone.Marionete environment to have a list of subviews, without manually rendering them, and consume as least as possible memmory.

The view with child views is rendered based on a template, and is a part of a tab control tabs. The tamplete for the tab view has divs, which are used as a placholders for child controls ( two collection views and two helper controls )

Several aproaches I've made already:

1) Create view instances in render method and, attach them to a propper el hardcoding the selectors in render method.

2) Extend a marionete layout and declare a regions for each view.

var GoalsView = Marionette.Layout.extend({

    template: '#goals-view-template',

    regions: {
        content: '#team-goals-content',
        homeFilter: '#team-goals-home-filter',
        awayFilter: '#team-goals-away-filter'
    },

    className: 'team-goals',

    initialize: function () {

        this.homeFilterView = new SwitchControlView({
            left: { name: 'HOME', key: 'home' },
            right: { name: 'ALL', key: 'all' },
        });

        this.awayFilterView = new SwitchControlView({
            left: { name: 'AWAY', key: 'away' },
            right: { name: 'ALL', key: 'all' },
        });

        this.сontentView = new GoalsCollecitonView({
            collection: statsHandler.getGoalsPerTeam()
        });
    },

    onShow: function () {
        this.content.show(this.сontentView);
        this.homeFilter.show(this.homeFilterView);
        this.awayFilter.show(this.awayFilterView);
    }
});

This is the cool way, but I am worried about the overhead for maintaing regions collection which will always display single view.

3) I extended marionette item view with the following logic:

var ControlsView = Marionette.ItemView.extend({
    views: {},

    onRender: function() {

        this.bindUIElements();

        for (var key in this.ui) {
            var view = this.views[key];
            if (view) {

                var rendered = view.render().$el;

                //if (rendered.is('div') && !rendered.attr('class') && !rendered.attr('id')) {
                //  rendered = rendered.children();
                //}

                this.ui[key].html(rendered);
            }
        }
    }
});

Which allowed me to write following code

var AssistsView = ControlsView.extend({

    template: '#assists-view-template',
    className: 'team-assists',

    ui: {
        content: '#team-assists-content',
        homeFilter: '#team-assists-home-filter',
        awayFilter: '#team-assists-away-filter'
    },

    initialize: function () {
        this.views = {};

        this.views.homeFilter = new SwitchControlView({
            left: { name: 'HOME', key: 'home' },
            right: { name: 'ALL', key: 'all' },
        });

        this.views.awayFilter = new SwitchControlView({
            left: { name: 'AWAY', key: 'away' },
            right: { name: 'ALL', key: 'all' },
        });

        this.views.content = new AssistsCollecitonView({
            collection: statsHandler.getAssistsPerTeam()
        });
    }
});

But it will leak memmory for sure, and I not feel like I will be able to write proper code to handle memmory leaks.

So in general, what I want, is to have a nice declarative way to create a view with other views as controls on it, with protection agains memmory leaks and least memmory consumption possible...

PS sorry for the wall of text

Why don't you simply use a layout and display your views within the layout's regions? You can see an example here: https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/apps/contacts/list/list_controller.js#L43-L46

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM