2012-08-10 8 views
8

Ho usato Marionette per una settimana e mi ha davvero reso la vita più facile!trigger caricamento vista quando raccolta o modello recuperato

In questo momento devo essere in grado di notificare a un utente quando viene raccolta una raccolta o un modello, perché alcune viste richiedono molto tempo per il rendering/recupero. Per fare un esempio ho fatto un piccolo mockup:

http://i.stack.imgur.com/IU3BP.png

Quando un utente fa clic su una categoria, una raccolta di tutti gli elementi all'interno di tale categoria devono essere caricati. Prima che la raccolta venga recuperata, voglio visualizzare una vista di caricamento come nell'immagine (vista 1). Quale sarebbe una soluzione elegante per implementarlo. Ho trovato il seguente post in cui un utente abilita un trigger di recupero: http://tbranyen.com/post/how-to-indicate-backbone-fetch-progress. Questo sembra funzionare ma non proprio come volevo. Questo è qualcosa che mi si avvicinò con:

var ItemThumbCollectionView = Backbone.Marionette.CollectionView.extend({ 
     collection: new ItemsCollection(userId), 
     itemView: ItemThumbView, 
     initialize: function(){ 
      this.collection.on("fetch", function() { 
       //show loading view 
      }, this); 
      this.collection.on("reset", function() { 
       //show final view 
      }, this); 
      this.collection.fetch(); 

      Backbone.history.navigate('user/'+identifier); 
      this.bindTo(this.collection, "reset", this.render, this) 
     } 
    }); 

Sarebbe bello però se potessi avere un attributo opzionale chiamato 'LoadItemView', per esempio. Quale sostituisce l'itemView durante il recupero. Questa sarebbe una buona pratica secondo te?

+0

Utilizzare collection.on ('request') invece di collection.on ('fetch'). E collection.fetch ({reset: true}) invece di collection.fetch(). ;) –

risposta

1

Pochi giorni fa, Derick Bailey ha registrato una possibile soluzione nel Marionette Wiki: https://github.com/marionettejs/backbone.marionette/wiki/Displaying-A-%22loading-...%22-Message-For-A-Collection-Or-Composite-View

+2

c'è un problema con questa soluzione, però. se il tuo recupero restituisce zero elementi, la schermata di "caricamento" non andrà mai via. –

+0

Penso che l'idea di Boedy sia sulla strada giusta. anche se sarei sicuro e userò 'this.bindTo (collection' invece di' this.collection.on') e potrei mettere questa logica in un oggetto separato, non direttamente nella vista, ma l'idea è buona, penso. –

+0

Grazie. Per ora la funzione emptyView funziona per me.Penso che posso far partire un evento se viene restituita una raccolta vuota. – Boedy

0
var myCollection = Backbone.Marionette.CollectionView.extend({ 
    initialize: function(){ 
     this.collection.on('request', function() { 
      //show loading here 
     }) 
     this.collection.on('reset', function() { 
      //hide loading here 
     }) 
     this.collection.fetch({reset: true}) 
    } 
}) 

E 'meglio ora, credo.

0

metodo Usa Backbone sincronizzazione

/* nel corso di guida di applicazione di sincronizzazione ogni richiesta venga sentire tranne ajax diretta */

Backbone._sync = Backbone.sync; 
Backbone.sync = function(method, model, options) { 
    // Clone the all options 
    var params = _.clone(options); 

params.success = function(model) { 
    // Write code to hide the loading symbol 
    //$("#loading").hide(); 
    if (options.success) 
     options.success(model); 
}; 
params.failure = function(model) { 
    // Write code to hide the loading symbol 
    //$("#loading").hide(); 
    if (options.failure) 
     options.failure(model); 
}; 
params.error = function(xhr, errText) { 
    // Write code to hide the loading symbol 
    //$("#loading").hide(); 
    if (options.error) 
     options.error(xhr, errText); 
}; 
// Write code to show the loading symbol 
    //$("#loading").show(); 
Backbone._sync(method, model, params); 

};

0

In generale, suggerirei di caricare un preloader durante il recupero dei dati, quindi di mostrare la raccolta. Qualcosa di simile:

region.show(myPreloader); 
collection.fetch().done(function() { 
    region.show(new MyCollectionView({ collection: collection }); 
});