2012-02-02 15 views
12

Ho cercato di associare un gestore all'evento di ridimensionamento in una delle mie viste Backbone. Dopo aver fatto alcune ricerche, ho scoperto che è possibile solo allegare eventi all'elemento della vista o ai suoi discendenti.Come si aggiunge un evento di ridimensionamento alla finestra in una vista utilizzando Backbone?

Questo è un problema per me perché l'effetto visivo che sto cercando di ottenere non è possibile utilizzando puro CSS e richiede del JS per impostare le dimensioni dell'elemento dell'area del contenuto in base alla finestra meno l'elemento dell'intestazione.

Se si hanno problemi a visualizzare quello che sto cercando di fare, immaginare un colpo di testa sottile e un'area di contenuto che deve occupare lo spazio rimanente senza CSS sfondo inganno;)

Ho allegato un esempio di codice. Se hai altri suggerimenti, mi piacerebbe anche ascoltarli!

define(
    [ 
     'jQuery', 
     'Underscore', 
     'Backbone', 
     'Mustache', 
     'text!src/common/resource/html/base.html' 
    ], 
    function ($, _, Backbone, Mustache, baseTemplate) { 
     var BaseView = Backbone.View.extend({ 

      el: $('body'), 

      events: { 
       'resize window': 'resize' 
      }, 

      render: function() { 
       var data = {}; 

       var render = Mustache.render(baseTemplate, data); 

       this.$el.html(render); 

       this.resize(); 
      }, 

      resize: function() { 
       var windowHeight = $(window).height(); 

       var headerHeight = this.$el.find('#header').height(); 

       this.$el.find('#application').height(windowHeight - headerHeight); 
      } 
     }); 

     return new BaseView; 
    } 
); 

Qualsiasi assistenza sarebbe molto apprezzata dal mio viso.

Grazie, Alex

risposta

25
var BaseView = Backbone.View.extend({ 

    el: $('body'), 

    initialize: function() { 
     // bind to the namespaced (for easier unbinding) event 
     // in jQuery 1.7+ use .on(...) 
     $(window).bind("resize.app", _.bind(this.resize, this)); 
    }, 

    remove: function() { 
     // unbind the namespaced event (to prevent accidentally unbinding some 
     // other resize events from other code in your app 
     // in jQuery 1.7+ use .off(...) 
     $(window).unbind("resize.app"); 

     // don't forget to call the original remove() function 
     Backbone.View.prototype.remove.call(this); 
     // could also be written as: 
     // this.constructor.__super__.remove.call(this); 
    }, ... 

Non dimenticare di chiamare la funzione remove() sulla vista. Non sostituire mai la vista con un'altra.

+0

Grazie per la tua risposta veloce! Ma è una cattiva pratica andare al di fuori del livello degli eventi di Backbone? –

+1

Direi che non ti preoccupare troppo. L'evento di ridimensionamento non interagisce in modo complesso con la struttura MVC, quindi non stai perdendo nulla semplicemente avendo un ascoltatore separato – wheresrhys

+0

Grazie per aver chiarito che per me –

4

È possibile consentire a window.onresize di attivare un evento personalizzato e quindi consentire a Views o Models di ascoltarlo per ottenere risposte personalizzate per vari elementi.

Caso 1. Una vista ascolta direttamente l'evento della finestra.

window.onload = function() { 

    _.extend(window, Backbone.Events); 
    window.onresize = function() { window.trigger('resize') }; 

    ViewDirect = Backbone.View.extend({ 

    initialize: function() { 
     this.listenTo(window, 'resize', _.debounce(this.print)); 
    }, 

    print: function() { 
     console.log('Window width, heigth: %s, %s', 
     window.innerWidth, 
     window.innerHeight); 
    }, 

    }); 

    var myview = new ViewDirect(); 

    } 

Caso 2. Si consiglia di mantenere le dimensioni della finestra senza ispezionare ogni volta che si ha bisogno, quindi, si memorizzare le dimensioni della finestra in un modello dorsale: in questo caso il modello di finestra ascolta la finestra , mentre la vista ascolta il modello della finestra:

window.onload = function() { 

    _.extend(window, Backbone.Events); 
    window.onresize = function() { window.trigger('resize') }; 

    WindowModel = Backbone.Model.extend({ 

    initialize: function() { 
     this.set_size(); 
     this.listenTo(window, 'resize', _.debounce(this.set_size)); 
    }, 

    set_size: function() { 
     this.set({ 
     width: window.innerWidth, 
     height: window.innerHeight 
     }); 
    } 

    }); 

    ViewWithModel = Backbone.View.extend({ 

    initialize: function() { 
     this.listenTo(this.model, 'change', this.print); 
     ... 
    }, 

    print: function() { 
     console.log('Window width, heigth: %s, %s', 
     this.model.width, 
     this.model.height); 
    }, 
    }); 

    var window_model = new WindowModel(); 
    var myview = new ViewWithModel({model: window_model}); 

} 
+0

c'è un motivo per cui il modello è coinvolto in questo processo evento? Normalmente penserei di ridimensionare come evento a livello di vista. – mlibby

+0

@mlibby dipende da cosa sta cambiando. È possibile che l'evento cambi il modello in modo che la vista debba riguardare solo gli eventi del modello. – prodaea

+1

Ciao @mlibby scusa per il replay in ritardo, non ho notato la tua domanda. Modificato per rispondere, anche per rimarcare quanto detto sopra. –

Problemi correlati