admin管理员组

文章数量:1244403

I'm getting into larger-scale data structures with Backbone, and ing across occasions where data would be well-represented via CompositeViews; that is, CollectionViews with the addition of "added fluff" around them, such as headers, buttons, and so on.

However, I'm having a lot of difficulty nesting CompositeViews inside one another. Using the standard itemView property on a CompositeView to render another CompositeView doesn't seem to be firing at all.

Assume I have a parent ItemView, instantiated as such (following Derick Bailey's example; assume this top level is where the initial fetch() on the collection would be called):

var User = Backbone.Model.extend({});

var UserCollection = Backbone.Collection.extend({
    model: User
});

var userList = new UserCollection(userData);

var schedulerCompositeView = new SchedulerCompositeView({
    collection: userList
});

schedulerCompositeView.render();

this.ui.schedulerWidget.html(schedulerCompositeView.el);

And SchedulerCompositeView looks as such:

return Backbone.Marionette.CompositeView.extend({
    template: Handlebarspile(schedulerCompositeViewTemplate),
    itemView: SchedulerDetailCompositeView,
    appendHtml: function (collectionView, itemView) {
        collectionView.$("#schedulerGroups").append(itemView.el);
    }
});

And finally, SchedulerDetailCompositeView:

return Backbone.Marionette.CompositeView.extend({
    template: Handlebarspile(schedulerDetailCompositeViewTemplate),
    itemView: SchedulerDetailItemView,
    appendHtml: function (collectionView, itemView) {
        collectionView.$("#schedulerDetailStops").append(itemView.el);
    }
});

SchedulerDetailCompositeView never gets instantiated; in fact, its appendHtml() method never seems to fire at all.

Clearly there's some other information missing here; obviously the intent is to pass a collection/model to SchedulerDetailCompositeView, but I'm not really sure what the proper technique for doing so is, due to the nested CompositeViews.

For reference, here's a rough mockup of the structure I'm trying to achieve; if there might be a better manner for reaching this goal than nested CompositeViews, I'm certainly all ears:

/

I'm getting into larger-scale data structures with Backbone, and ing across occasions where data would be well-represented via CompositeViews; that is, CollectionViews with the addition of "added fluff" around them, such as headers, buttons, and so on.

However, I'm having a lot of difficulty nesting CompositeViews inside one another. Using the standard itemView property on a CompositeView to render another CompositeView doesn't seem to be firing at all.

Assume I have a parent ItemView, instantiated as such (following Derick Bailey's example; assume this top level is where the initial fetch() on the collection would be called):

var User = Backbone.Model.extend({});

var UserCollection = Backbone.Collection.extend({
    model: User
});

var userList = new UserCollection(userData);

var schedulerCompositeView = new SchedulerCompositeView({
    collection: userList
});

schedulerCompositeView.render();

this.ui.schedulerWidget.html(schedulerCompositeView.el);

And SchedulerCompositeView looks as such:

return Backbone.Marionette.CompositeView.extend({
    template: Handlebars.pile(schedulerCompositeViewTemplate),
    itemView: SchedulerDetailCompositeView,
    appendHtml: function (collectionView, itemView) {
        collectionView.$("#schedulerGroups").append(itemView.el);
    }
});

And finally, SchedulerDetailCompositeView:

return Backbone.Marionette.CompositeView.extend({
    template: Handlebars.pile(schedulerDetailCompositeViewTemplate),
    itemView: SchedulerDetailItemView,
    appendHtml: function (collectionView, itemView) {
        collectionView.$("#schedulerDetailStops").append(itemView.el);
    }
});

SchedulerDetailCompositeView never gets instantiated; in fact, its appendHtml() method never seems to fire at all.

Clearly there's some other information missing here; obviously the intent is to pass a collection/model to SchedulerDetailCompositeView, but I'm not really sure what the proper technique for doing so is, due to the nested CompositeViews.

For reference, here's a rough mockup of the structure I'm trying to achieve; if there might be a better manner for reaching this goal than nested CompositeViews, I'm certainly all ears:

http://jsfiddle/KAWB8/

Share Improve this question asked Nov 26, 2012 at 23:42 user846062user846062 2
  • 2 Inside SchedulerDetailCompositeView initialize function you will have explicitly assign a value to this.collection i.e tell the posite view about the collection its dealing with. Like in this treeview fiddle – deven98602 Commented Nov 27, 2012 at 12:16
  • This doesn't seem to be enough information. Even after assigning a collection via the initialize method, the appendHtml on the SchedulerDetailCompositeView never actually fires. Initialize does, but appendHtml doesn't. – user846062 Commented Nov 27, 2012 at 22:03
Add a ment  | 

1 Answer 1

Reset to default 16

Eureka! I was set upon the correct path by deven98602.

The key to remember is that, if you're nesting multiple CompositeViews (or CollectionViews), each cascading level down will represent one unit of the set from its parent; that is, my SchedulerDetailCompositeView from before represents a single model from the collection in SchedulerCompositeView. Therefore, if I'm constructing nested CompositeViews (presumably based on deeply-nested data), I must redefine a collection on these cascaded children, as they only have a single model associated with them, and not a proper collection to render.

That said, the updated SchedulerDetailCompositeView looks as such:

return Backbone.Marionette.CompositeView.extend({
    template: Handlebars.pile(schedulerDetailCompositeViewTemplate),
    itemView: SchedulerDetailItemView,
    initialize: function () {
        var Load = Backbone.Model.extend();

        var LoadCollection = Backbone.Collection.extend({
            model: Load
        });

        // this array of loads, nested within my JSON data, represents
        //  a new collection to be rendered as models using SchedulerDetailItemView
        var loadList = new LoadCollection(this.model.get("loads"));

        this.collection = loadList;
    },
    appendHtml: function (collectionView, itemView) {
        collectionView.$("#schedulerDetailStops").append(itemView.el);
    }
});

Once the collection is set, appendHtml() fires as expected and renders each new model in this newly-set collection.

本文标签: javascriptHow to handle nested CompositeView using BackboneMarionetteStack Overflow