2012-02-24 2 views
8

Penso che quello che voglio fare sia piuttosto semplice, semplicemente non so come farlo. Vorrei attivare il mio evento quando uno dei miei modelli attribuisce modifiche allo scopo di passare alcuni dati al gestore di eventi (se il cambiamento è stato un aumento o una diminuzione di valore).Sovrascrittura di un evento di modifica di modelli backbone

Fondamentalmente io voglio che il mio gestore per fare questo nella vista

handler: function(increased) { 
    if(increased) { 
     alert("the value increased") 
    } 
    else { 
     alert("the value decreased") 
    } 
} 

// ... 

this.model.on("change:attr", this.handler, this); 
+1

Che cosa non funziona? – tkone

+0

hmmm forse la mia domanda non è chiara, voglio sapere come posso passare i dati al gestore 'change: attr', proprio ora che l'evento viene sparato "automagicamente" da backbone, ogni volta che chiamo 'set()' sul mio modello. – Matthew

+0

Quali dati si desidera passare? Avrai già accesso al modello e saprai quale attributo è stato modificato. – tkone

risposta

12

Ecco qua: in pratica ascolti change:myvar. Quando si verifica una modifica, utilizzare il modello previous() per ottenere il valore precedente. A seconda che sia aumentato o diminuito, l'evento appropriato viene attivato. Puoi ascoltare questi eventi come mostrato nello initialize().

(function($){ 

    window.MyModel = Backbone.Model.extend({ 

     initialize: function() { 
      this.on('change:myvar', this.onMyVarChange); 
      this.on('increased:myvar', function() {     
       console.log('Increased');     
      }); 
      this.on('decreased:myvar', function() {     
       console.log('Decreased');     
      }); 
     }, 

     onMyVarChange: function() { 
      if (this.get('myvar') > this.previous('myvar')) { 
       this.trigger('increased:myvar'); 
      } else { 
       this.trigger('decreased:myvar'); 
      } 
     }    
    }); 

    window.mymodel = new MyModel({myvar: 1}); 
    mymodel.set({myvar: 2}); 
    mymodel.set({myvar: 3}); 
    mymodel.set({myvar: 1}); 

})(jQuery);​ 

L'esecuzione di quanto sopra verrà stampato "Aumentato", "Aumentato", "Diminuito" sulla console.

+0

Questa sembra una soluzione molto bella. Lo testeremo e torneremo a voi ... – Matthew

+0

funziona benissimo, accettato – Matthew

+0

Funziona piuttosto bene, grazie per l'heads up. Per il mio caso, avevo bisogno di rilevare l'evento nella vista che ha un modello allegato. Quindi l'evento 'change: attribute_name' è stato attivato anche quando il modello viene collegato alla vista oltre a quando il valore del modello viene modificato dall'input DOM. Quindi ho dovuto verificare se 'this.model.get ('attribute_name')' è 'null' per evitare di rilevare l'evento attivato in vista del metodo' initialize'. – codarrior

0

Che cosa succede se si spara il proprio evento personalizzato dopo aver ascoltato l'evento di modifica?

handler: function(increased) { 
    this.model.trigger('my-custom-event', stuff, you, want); 
}, 
myHandler: function(stuff, you, want){ 
    // Do it... 
} 
// ... 
this.model.on("change:attr", this.handler, this); 
this.model.on('my-custom-event, this.myHandler, this); 
2

Basta guardare previousAttributes()

È quindi possibile confrontare:

If(this.get(attr) > this.previousAttributes()[attr]){ 
    console.log('bigger'); 
} else { 
    console.log('smaller'); 
} 

Se si usa che nel vostro gestore di eventi change è tutto pronto. Non è necessario un trigger personalizzato o una tonnellata di codice.

EDIT

Questo è dal mio progetto Backbone.Validators e come ottengo la lista di tutti gli attributi che sono stati modificati durante la fase di validazione:

var get_changed_attributes = function(previous, current){ 
    var changedAttributes = []; 
    _(current).each(function(val, key){ 
     if(!_(previous).has(key)){ 
      changedAttributes.push(key); 
     } else if (!_.isEqual(val, previous[key])){ 
      changedAttributes.push(key); 
     } 
    }); 
    return changedAttributes; 
}; 

Ciò richiede sottolineatura 1.3.1 perché sta usando _.has. Se non è possibile aggiornare è una cosa facile da sostituire però. Nel tuo caso passeresti il ​​this.previousAttributes() e il this.attributes

+0

sembra simile a ciò che @ggozad ha creato. L'ho accettato perché mi piaceva l'idea di ascoltare "this.on ('changed: attr'' e attivare un evento personalizzato nel gestore.) Grazie per il tuo aiuto però :) – Matthew

+0

@matthew Yup. Questo è il modo migliore per farlo.L'idea per questo è che puoi farlo genericamente confrontando gli attributi che rendono più facile il riutilizzo se necessario. Grazie per il feedback! – tkone