How do you properly display a Backbone marionette collection view based on a model javascript array property?

我只是一个虾纸丫 提交于 2020-01-01 05:26:08

问题


*UPDATE: See final answer code in the last code block below.*

Currently I am having an issue displaying a collection in a collection view. The collection is a property of an existing model like so (pseudo code)

ApplicationVersion { Id: 1, VersionName: "", ApplicationCategories[] }

So essentially ApplicationVersion has a property called ApplicationCategories that is a javascript array. Currently when I render the collection view associated with ApplicationCategories nothing is rendered. If I debug in Chrome's javascript debugger it appears that the categories have not been populated yet (so I assume ApplicationVersion has not been fetched yet). Here is my code as it stands currently

ApplicationCategory Model, Collection, and Views

ApplicationModule.ApplicationCategory = Backbone.Model.extend({
    urlRoot:"/applicationcategories"
});

ApplicationModule.ApplicationCategories = Recruit.Collection.extend({
    url:"/applicationcategories",
    model:ApplicationModule.ApplicationCategory,

    initialize: function(){
        /*
         * By default backbone does not bind the collection change event to the comparator
         * for performance reasons.  I am choosing to not preoptimize though and do the
         * binding.  This may need to change later if performance becomes an issue.
         * See https://github.com/documentcloud/backbone/issues/689
         *
         * Note also this is only nescessary for the default sort.  By using the
         * SortableCollectionMixin in other sorting methods, we do the binding
         * there as well.
         */
        this.on("change", this.sort);
    },

    comparator: function(applicationCategory) {
        return applicationCategory.get("order");
    },

    byName: function() {
        return this.sortedBy(function(applicationCategory) {
            return applicationCategory.get("name");
        });
    }
});

_.extend(ApplicationModule.ApplicationCategories.prototype, SortableCollectionMixin);

ApplicationModule.ApplicationCategoryView = Recruit.ItemView.extend({
    template:"application/applicationcategory-view-template"
});

ApplicationModule.ApplicationCategoriesView = Recruit.CollectionView.extend({
    itemView:ApplicationModule.ApplicationCategoryView
});

ApplicationCategory template

<section id="<%=name%>">
   <%=order%>
</section>

ApplicationVersion Model, Collection, and Views

ApplicationModule.ApplicationVersion = Backbone.Model.extend({
    urlRoot:"/applicationversions"
});

ApplicationModule.ApplicationVersions = Recruit.Collection.extend({
    url:"/applicationversions",
    model:ApplicationModule.ApplicationVersion
});

ApplicationModule.ApplicationVersionLayout = Recruit.Layout.extend({
    template:"application/applicationversion-view-template",

    regions: {
        applicationVersionHeader: "#applicationVersionHeader",
        applicationVersionCategories: "#applicationVersionCategories",
        applicationVersionFooter: "#applicationVersionFooter"
    }
});

ApplicationModule.ApplicationVersionController = {
    showApplicationVersion: function (applicationVersionId) {
        ApplicationModule.applicationVersion = new ApplicationModule.ApplicationVersion({id : applicationVersionId});

        var applicationVersionLayout = new Recruit.ApplicationModule.ApplicationVersionLayout({
            model:ApplicationModule.applicationVersion
        });

        ApplicationModule.applicationVersion.fetch({success: function(){
            var applicationVersionCategories = new Recruit.ApplicationModule.ApplicationCategoriesView({
                collection: ApplicationModule.applicationVersion.application_categories
            });
            applicationVersionLayout.applicationVersionCategories.show(applicationVersionCategories);
        }});

        // Fake server responds to the request
        ApplicationModule.server.respond();

        Recruit.layout.main.show(applicationVersionLayout);
    }
};

Here is my ApplicationVersion template

<section id="applicationVersionOuterSection">
<header id="applicationVersionHeader">
    Your Application Header <%= id %>
</header>
<section id="applicationVersionCategories">
</section>
<footer id="applicationVersionFooter">
     Your footer
</footer>

One thing to note I am currently using Sinon to mock my server response, but I don't think this is causing the issues as it is responding with the information as I expect looking through the javascript debugger (and like I said it is displaying ApplicationVersion id correctly). I can provide this code as well if it helps

It is currently displaying the application version id (id in the template), so I know it is fetching the data correctly for normal properties, it just is not rendering my ApplicationCategories javascript array property.

So ultimately I am binding to the success of the fetch for ApplicationVersion, then setting up the view for the ApplicationCategories. Since this isn't working like I expect I am wondering if there is a better way to create this collection view?

Thanks for any help

UPDATE: Working code example that Derek Bailey lead me too.

ApplicationModule.ApplicationVersionController = {
    showApplicationVersion: function (applicationVersionId) {
        ApplicationModule.applicationVersion = new ApplicationModule.ApplicationVersion({id : applicationVersionId});

        var applicationVersionLayout = new Recruit.ApplicationModule.ApplicationVersionLayout({
            model:ApplicationModule.applicationVersion
        });

        ApplicationModule.applicationVersion.fetch();

        // Fake server responds to the request
        ApplicationModule.server.respond();

        Recruit.layout.main.show(applicationVersionLayout);

        var applicationVersionCategories = new Recruit.ApplicationModule.ApplicationCategoriesView({
            collection: new Backbone.Collection(ApplicationModule.applicationVersion.get('application_categories'))
        });
        applicationVersionLayout.applicationVersionCategories.show(applicationVersionCategories);
    }
};

回答1:


Marionette's CollectionView requires a valid Backbone.Collection, not a simple array. You need to create a Backbone.Collection from your array when passing it to the view:


new MyView({
  collection: new Backbone.Collection(MyModel.Something.ArrayOfThings)
});


来源:https://stackoverflow.com/questions/11838390/how-do-you-properly-display-a-backbone-marionette-collection-view-based-on-a-mod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!