2012-09-16 16 views
10

Sto provando a impostare le animazioni sul rendering e sulla chiusura di un oggetto con Backbone.Marionette. Per il rendering di una vista, questo è abbastanza semplice:Backbone.Marionette: posticipa chiudi chiudi fino a primaClima animazione è completa

MyItemView = Backbone.Marionette.View.extend({ 
    ... 
    onRender: function() { 
    this.$el.hide().fadeIn(); 
    } 
    ... 
}); 

Questo renderà la mia vista sfumata quando lo renderò. Ma diciamo che voglio svanire il mio punto di vista da vicino.

beforeClose: function() { 
    this.$el.fadeOut();  // doesn't do anything.... 
} 

questo non funzionerà, perché l'articolo si chiude immediatamente dopo la chiamata this.beforeClose(), quindi l'animazione non ha il tempo per completare.

C'è qualche modo, usando Marionette così com'è, per realizzare un'animazione di chiusura?


In alternativa, questa è la soluzione che ho usato:

_.extend(Backbone.Marionette.ItemView.prototype, { 
    close: function(callback) { 

     if (this.beforeClose) { 

      // if beforeClose returns false, wait for beforeClose to resolve before closing 
      // Before close calls `run` parameter to continue with closing element 
      var dfd = $.Deferred(), run = dfd.resolve, self = this; 
      if(this.beforeClose(run) === false) { 
       dfd.done(function() { 
        self._closeView();    // call _closeView, making sure our context is still `this` 
       }); 
       return true; 
      } 
     } 

     // Run close immediately if beforeClose does not return false 
     this._closeView(); 
    }, 

// The standard ItemView.close method. 
    _closeView: function() { 
     this.remove(); 

     if (this.onClose) { this.onClose(); } 
     this.trigger('close'); 
     this.unbindAll(); 
     this.unbind();  
    } 
}); 

ora posso fare questo:

beforeClose: function(run) { 
    this.$el.fadeOut(run);  // continue closing view after fadeOut is complete 
    return false; 
}, 

Sono nuovo di utilizzare Marionette, così ho Non sono sicuro se questa sia la soluzione migliore. Se questo è il modo migliore, invierò una richiesta di pull, anche se vorrò riflettere un po 'su come questo potrebbe funzionare con altri tipi di visualizzazioni.

Questo potrebbe essere potenzialmente utilizzato per altri scopi, come chiedere conferma alla chiusura (vedere questo issue), o eseguire qualsiasi tipo di richiesta asincrona.

Pensieri?

risposta

18

override del metodo close è l'unico modo per fare questo, ma si può scrivere po 'più breve, come è possibile chiamare il Marionette close metodo invece di duplicarlo:

_.extend(Backbone.Marionette.ItemView.prototype, { 
    close: function(callback) { 
     var close = Backbone.Marionette.Region.prototype.close; 
     if (this.beforeClose) { 

      // if beforeClose returns false, wait for beforeClose to resolve before closing 
      // Before close calls `run` parameter to continue with closing element 
      var dfd = $.Deferred(), run = dfd.resolve, self = this; 
      if(this.beforeClose(run) === false) { 
       dfd.done(function() { 
        close.call(self); 
       }); 
       return true; 
      } 
     } 

     // Run close immediately if beforeClose does not return false 
     close.call(this); 
    }, 


}); 

Un'altra idea è quella di overide il remove metodo della tua vista. Quindi svanisci l'elemento della vista e rimuovilo dal DOM

remove: function(){ 
    this.$el.fadeOut(function(){ 
    $(this).remove(); 
    }); 
} 
+0

Ah ... grazie! Sapevo che doveva esserci un modo più semplice e sovrascrivere View.remove mi sembra più semplice. BTW, nel callback di fadeOut, dovrai chiamare '$ (this) .remove()', o 'Backbone.Marionette.ItemView.prototype.call (self)' – eschwartz

+0

Ignorare la funzione di rimozione è una soluzione migliore di annullando il metodo close. Questo ha funzionato alla grande per me. Grazie. – earl3s