问题
*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