我正在显示一个CompositeView,其中每个模型都有一个属性,它是图像的URL。如果我只是。在一个区域中显示图像尚未完成加载,这看起来不太性感(它们在加载时会显示)。
在显示视图之前,我想等到所有图像都已加载。现在,我试图通过延迟图像加载来使其工作,但这可能不是正确的方法(也许这应该在模型上完成?)。
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);
});
});
}
};
});
答案 0 :(得分:1)
我认为你的方法是正确的,我会尝试将数据/图像加载封装在一个函数中,可能使用存储库
$.when(applicationsRepository.getAll()).then(function (apps) {
var appsView = new App.Views.ApplicationListView({ collection: apps});
App.layout.mainRegion.show(appsView );
});
所以,这个代码将成为你控制器的一部分,就像你已经拥有它一样,当存储库完成加载时,控制器只是在视图上呈现数据,类似于带有存储库的服务器端MVC,
getAll()将包含您现在在控制器上加载数据和图像的代码,存储库将是您木偶应用程序的额外模块。
所以你的方法getAll就像
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 });
};
要在最后一个图像加载后识别并执行某些操作(回调),我可能会使用一个计数器设置总图像数(来自集合),并在每次执行加载处理程序时递减它。 $(window).load()可以是,并且在加载整个页面后将触发选项。
感谢。
答案 1 :(得分:0)
我最终这样做(灵感来自Wait for image to be loaded before going on):
applications/list_controller.js
App.module("ApplicationsApp.List", function(List, App, Backbone, Marionette, $, _) {
List.Controller = {
listApplications: function() {
self = this;
// Set layout
App.trigger("set:layout:authenticated");
// Fetch the applications
var fetchingApplications = App.request('application:entities');
// Perform actions when applications have been fetched
$.when(fetchingApplications).done(function(applications) {
// Load all images in applications
var imgLoaders = [];
applications.each(function(application) {
var src = application.get("image_path");
imgLoaders.push(self.loadImage(src));
});
// Perform actions when images have been loaded
$.when.apply($, imgLoaders).done(function() {
var applicationsListView = new List.Applications({
collection: applications
});
App.layout.mainRegion.show(applicationsListView);
});
});
},
loadImage: function(src) {
var deferred = $.Deferred();
var img = new Image();
img.onload = function() {
deferred.resolve();
};
img.src = src;
return deferred.promise();
}
};
});