Im displaying a CompositeView, in which each model has a property which is an url for an image. If I just .show the view in a region the images have not finished loading, which doesnt look very sexy (they are displayed when they have loaded).
I would like to wait until all images have loaded, before I display the view. Right now, Im trying to make it work by deferring image loads, but this is probably not the right way (perhaps this should be done on the model?).
applications/list_view.js
App.module("ApplicationsApp.List", function(List, App, Backbone, Marionette, $, _){
List.Application = Marionette.ItemView.extend({
tagName: 'li',
template: Templates.applications.application
});
List.Applications = Marionette.CompositeView.extend({
className: "applications",
template: Templates.applications.applications,
childView: List.Application,
childViewContainer: "ul"
});
});
applications/list_controller.js
App.module("ApplicationsApp.List", function(List, App, Backbone, Marionette, $, _) {
List.Controller = {
listApplications: function() {
// Set layout
App.trigger("set:layout:authenticated");
// Fetch the applications
var fetchingApplications = App.request('application:entities');
$.when(fetchingApplications).done(function(applications) {
var applicationsListView = new List.Applications({
collection: applications
});
var deferreds = [];
applications.each(function(application) {
deferreds.push(function() {
var loader = new Image();
loader.onload = function() {
console.log(application.get("image_path"));
};
loader.src = application.get("image_path");
});
});
$.when.apply($, deferreds).then(function() {
App.layout.mainRegion.show(applicationsListView);
});
});
}
};
});
I think your approach is correct, I will try to encapsulate the data/image loading in one function, using a repository probably
$.when(applicationsRepository.getAll()).then(function (apps) {
var appsView = new App.Views.ApplicationListView({ collection: apps});
App.layout.mainRegion.show(appsView );
});
So, this code will be part of you controller, as you already have it, when the repository finish the loading the controller just render the data on the view, something similar to server side MVC with repositories,
getAll() will contain the code that you have now on the controller to load the data and images, the repository will be an extra module on your marionette application.
So your method getAll will be something like
var getAll = function () {
var deferred = $.Deferred();
_getAll(function (apps) {
deferred.resolve(apps);
});
return deferred.promise();
};
var _getAll = function (callback) {
//code to create the app collection
apps.on("reset", function(apps){
//load images
//callback(apps);
});
apps.fetch({ reset: true });
};
To identify and perform some action(callback) after the last image loads, I will probably use a counter set at the total number of images(from the collection), and decrement it each time a load handler is executed. $(window).load() could be and option this will fire after the entire page is loaded.
Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With