2012-08-10 3 views
8

Ich benutze Marionette seit einer Woche und es hat mein Leben wirklich einfacher gemacht!trigger loading view wenn Sammlung oder Model geholt

Im Moment muss ich in der Lage sein, einen Benutzer zu benachrichtigen, wenn eine Sammlung oder ein Modell abgerufen wird, da einige Ansichten eine beträchtliche Zeit zum Rendern benötigen. Um ein Beispiel zu geben, ich habe ein kleines Mockup gemacht:

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

Wenn ein Benutzer klickt auf eine Kategorie, eine Sammlung aller Elemente innerhalb dieser Kategorie müssen geladen werden. Bevor die Sammlung abgerufen wird, möchte ich eine Ladeansicht wie im Bild angezeigt anzeigen (Ansicht 1). Was wäre eine elegante Lösung, dies zu implementieren. Ich habe den folgenden Beitrag gefunden, bei dem ein Benutzer einen Abruftrigger aktiviert: http://tbranyen.com/post/how-to-indicate-backbone-fetch-progress. Das scheint zu funktionieren, aber nicht wirklich wie ich es wollte. Das ist etwas, was ich kam mit:

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

Es wäre zwar schön, wenn ich ein optionales Attribut ‚LoadItemView‘ zum Beispiel genannt haben könnte. Das überschreibt die ItemView während eines Abrufs. Wäre das Ihrer Meinung nach eine gute Praxis?

+0

Verwenden Sie collection.on ('Anfrage') anstelle von collection.on ('fetch'). Und collection.fetch ({reset: true}) anstelle von collection.fetch(). ;) –

Antwort

1

Vor ein paar Tagen, Derick Bailey eine mögliche Lösung in der Mario Wiki geschrieben: https://github.com/marionettejs/backbone.marionette/wiki/Displaying-A-%22loading-...%22-Message-For-A-Collection-Or-Composite-View

+2

es gibt jedoch ein Problem mit dieser Lösung. Wenn Ihr Abruf null Elemente zurückgibt, wird der "Lade" -Bildschirm niemals verschwinden. –

+0

Ich denke Boedy Idee ist auf dem richtigen Weg. obwohl ich sicher wäre und 'this.bindTo (collection' anstelle von 'this.collection.on'.) verwende und diese logik in ein separates objekt, nicht direkt in die view einfügen könnte. aber die idee ist gut, denke ich. –

+0

Vielen Dank für den Moment funktioniert die leere Ansicht für mich.Ich denke, ich kann nur ein Ereignis auslösen, wenn eine leere Sammlung zurückgegeben wird – 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}) 
    } 
}) 

Es ist nun besser, glaube ich.

0

Verwenden Backbone Synchronisierungsmethode

/* über Reiten von Sync-Anwendung jede Anfrage direkt außer Ajax hören kommen */

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

Im Allgemeinen würde ich vorschlagen, einen Preloader während des Abrufs von Daten zu laden und dann die Sammlung anzuzeigen. Etwas wie:

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