Reputation: 73
I try to build a simple music library to learn Backbone.js. Evrything worked fine until I tried to load the data from a JSON file (instead of inline javascript object).
Here is my Javascript :
(function(){
var myMusic = {
Models : {},
Collections : {},
Views : {},
Routers : {}
};
// Model
myMusic.Models.Album = Backbone.Model.extend({
default: {
title : null,
artist : null,
cover : null,
publicationYear : null
},
initialize: function(){
console.log("Creation of the album " + this.get('title') + " from the artist " + this.get('artist'));
}
});
// Collection
myMusic.Collections.Albums = Backbone.Collection.extend({
model : myMusic.Models.Album,
url : "albums.json",
initialize : function(){
console.log("New collection created");
}
});
// Collection instance
var albumsCollection = new myMusic.Collections.Albums();
albumsCollection.fetch();
// Collection view
myMusic.Views.albums = Backbone.View.extend({
el: $("#albumsList"),
initialize: function() {
this.template = _.template($("#albumTemplate").html());
},
render: function () {
this.$el.html(this.template({ albums: albumsCollection.toJSON() }));
return this;
}
});
// Collection view instance
var albumsView = new myMusic.Views.albums({ collection : albumsCollection });
albumsView.render();
})();
The HTML part :
<div class="albumsListWrapper">
<script type="text/template" id="albumTemplate">
<% _.each(albums, function(album) { %>
<article>
<header>
<h1><%= album.title %></h1>
<h2><%= album.artist %></h2>
<h3><%= album.publicationYear %></h3>
</header>
<figure><img src="<%= album.cover %>" alt="<%= album.title %>" /></figure>
</article>
<% }); %>
</script>
<div id="albumsList" class="albumsList"></div>
</div>
And my JSON file :
[
{
"title" : "Gish",
"artist" : "Smashing Pumpkins",
"cover" : "http://ecx.images-amazon.com/images/I/51sGOPMVD9L.jpg",
"publicationYear" : 1991
},
{
"title" : "Siamese dream",
"artist" : "Smashing Pumpkins",
"cover" : "http://static.stereogum.com/uploads/2013/07/The-Smashing-Pumpkins-Siamese-Dream.jpg",
"publicationYear" : 1993
},
{
"title" : "Mellon Collie and the Infinite Sadness",
"artist" : "Smashing Pumpkins",
"cover" : "https://upload.wikimedia.org/wikipedia/fi/7/7e/Smashing_Pumpkins_-_Mellon_Collie_And_The_Infinite_Sadness.jpg",
"publicationYear" : 1995
},
{
"title" : "Adore",
"artist" : "Smashing Pumpkins",
"cover" : "https://s3.amazonaws.com/thisismyjam/i/6b4a1443ce6697a11537102f05b00f61.jpg",
"publicationYear" : 1998
},
{
"title" : "Machina/The Machines of God",
"artist" : "Smashing Pumpkins",
"cover" : "http://yourlifeisnotyourown.files.wordpress.com/2012/02/machinathemachinesofgod.jpg",
"publicationYear" : 2000
},
{
"title" : "Machina II",
"artist" : "Smashing Pumpkins",
"cover" : "http://vignette1.wikia.nocookie.net/lyricwiki/images/8/86/The_Smashing_Pumpkins-MACHINA_II_(2000).jpg",
"publicationYear" : 2000
},
{
"title" : "Zeitgeist",
"artist" : "Smashing Pumpkins",
"cover" : "https://s3.amazonaws.com/rapgenius/Zeitgeist.jpg",
"publicationYear" : 2007
},
{
"title" : "Oceania",
"artist" : "Smashing Pumpkins",
"cover" : "http://ecx.images-amazon.com/images/I/61HWLX-iGwL.jpg",
"publicationYear" : 2012
},
{
"title" : "Monuments to an Elegy",
"artist" : "Smashing Pumpkins",
"cover" : "http://lecanalauditif.ca/wp-content/uploads/2015/01/Monuments_to_an_Elegy_album_cover_from_Smashing_Pumpkins.jpg",
"publicationYear" : 2014
}
]
The issue seems to be located on the albumsCollection object. When I console.log it, it's empty :(
Any ideas ?
Upvotes: 0
Views: 348
Reputation: 21564
I think your problem comes from the fact that albums are not loaded yet when you render your view. You could listen to "sync" event to avoid that.
myMusic.Views.albums = Backbone.View.extend({
el: $("#albumsList"),
initialize: function () {
this.template = _.template($("#albumTemplate")
.html());
this.listenTo(this.collection,"sync",this.onSync)
},
onSync:function () {
this.render();
//other logic
},
render: function () {
this.$el.html(this.template({
albums: this.collection.toJSON()
}));
return this;
}
});
you should also avoid using external reference to your album collection inside your view and use the internal property this.collection
instead of albumsCollection
in render()
method.
Upvotes: 1