2014-10-27 76 views
3

Im顯示一個CompositeView,其中每個模型都有一個屬性,它是圖像的url。如果我只是在區域中顯示視圖,圖像尚未完成加載,這看起來不太性感(它們在加載時顯示)。Backbone Marionette:在所有圖像加載之前不要顯示視圖

我想在顯示視圖之前等待所有圖像加載完畢。現在,我試圖通過推遲圖像加載來實現它,但這可能不是正確的方式(也許這應該在模型上完成)。

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

你是問,如果這東西在模型或什麼辦?我認爲這種觀點應該處理圖像加載 – Dethariel 2014-10-27 14:12:33

+0

Naah。模型問題只是一個子問題:) 我想最好的解決方案。 – tolborg 2014-10-27 14:27:06

+0

最好的解決方案是檢查是否加載了所有圖像,然後渲染您的視圖。您可以將該邏輯(圖像加載檢查)提取到集合。看看[這裏](http://stackoverflow.com/questions/18974517/javascript-check-if-images-are-loaded-before-gameloop)和[這裏](http://stackoverflow.com/questions/15587330/測試,如果所有的圖像被加載) – 2014-10-27 14:35:46

回答

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()可能是和選項,這將在整個頁面加載後觸發。

謝謝。

+0

這似乎很有前途(得到的笑話?)。您能否在我的代碼中詳細闡述一下? – tolborg 2014-10-27 21:27:26

+0

這很有趣,我編輯了我的答案,希望它有幫助。 – 2014-10-27 21:52:53

+0

謝謝。你幫我寫了一個解決方案。你覺得怎麼樣?(我知道loadImage函數的位置可能不是很好,但到目前爲止,它是我使用它的應用程序中的唯一位置)。 – tolborg 2014-10-27 22:45:39

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(); 
 
    } 
 

 
    }; 
 

 
});

相關問題