2012-02-10 11 views
24

Consultare la soluzione per un'altra domanda fornita da ud3323: http://jsfiddle.net/ud3323/ykL69/. Questa soluzione evidenzia il valore modificato utilizzando il colore rosso. Ho un ulteriore requisito: se il valore è aumentato evidenzia in verde, se ha diminuito l'evidenziazione in colore rosso. Per questo, ho bisogno di conoscere i vecchi e i nuovi valori nel mio osservatore. C'è un modo per fare questo?Come può un osservatore scoprire i valori precedenti e successivi della proprietà osservata in Ember.js?

P.S. I documenti Embers non dicono nulla di ciò che è disponibile nella funzione di osservatore. Tutto quello che posso dire dall'esempio è che poiché l'osservatore è definito in itemRowView, "this" punta a itemRowView.

risposta

12

Date un'occhiata a beforeObserver s. Un beforeObserver si attiva prima che una proprietà cambi. Quindi se tu hai get la proprietà in un beforeObserver, avrai il valore di pre-cambiamento. Si imposta questo tipo di osservatore usando Ember.addBeforeObserver o tramite l'estensione del prototipo di funzione observesBefore.

Questo ti darebbe quello che ti serve per raggiungere il tuo obiettivo. Ho creato il seguente JSBin basato sul tuo violino per dimostrarlo qui: http://emberjs.jsbin.com/qewudu/2/edit

AGGIORNATO il 2014-10-07 per riflettere il comportamento in Ember 1.7.x.

AGGIORNAMENTO 2015-02: beforeObserver è stato dichiarato obsoleto. Vedi altre risposte a questa domanda.

+0

Ember.addBeforeObserver è molto più pulito. Grazie Luca! – Naresh

+11

BTW, ho notato recentemente che esiste un'estensione 'observesBefore' sulla funzione, quindi il codice può essere reso più gradevole come in http://jsfiddle.net/ye3M2/ –

+3

Non credo che venga fornito il 'valore'. Sto testando nella versione 1.5.1 – Denzo

2

Usa willInsertElement per memorizzare il valore iniziale, e sulla modifica del valore, confrontare i due:

Quotes.itemRowView = Ember.View.extend({ 
    tagName: 'tr', 

    initialValue: null, 

    willInsertElement: function(){ 
     var value = this.get('content').value; 
     this.set('initialValue', value); 
    }, 

    valueDidChange: function() { 
     // only run if updating a value already in the DOM 
     if(this.get('state') === 'inDOM') { 
      var new_value = this.get('content').value; 
      // decreased or increased? 
      var color = (new_value > this.get('initialValue')) ? 
       'green' : 'red' ; 
      // store the new value 
      this.set('initialValue', new_value); 
      // only update the value element color 
      Ember.$(this.get('element')).find('.quote-value').css('color', color); 
     } 
    }.observes('content.value') 
}); 

Date un'occhiata al jsfiddle http://jsfiddle.net/ykL69/15/

+0

Grazie Zack. Funziona molto bene. Tuttavia, se la mia comprensione è corretta, c'è un errore in questo codice. Sembra che willInsertElement() venga chiamato una sola volta (quando l'elemento viene inserito inizialmente). Pertanto, per mantenere i colori in modo corretto, alla fine di valueDidChange() sarà necessario reinizializzare il valore iniziale del nuovo valore, assicurandosi che la modifica successiva venga confrontata con questo valore. Mentre questo approccio funziona nel complesso, la vista sta diventando un luogo in cui memorizzare i valori. Invece se l'osservatore potesse fornire il vecchio e il nuovo valore, il codice potrebbe essere molto più semplice. – Naresh

+0

corretta la mia risposta. Sembra che beforeObserver, come dice @Luke, possa raggiungere lo stesso risultato. –

+0

Sono d'accordo. Grazie. – Naresh

16

beforeObserver è stato deprecated in Ember 1.10.

Al contrario, utilizzare una cache manuale:

doSomething: Ember.observer('foo', function() { 
    var foo = this.get('foo'); 
    var oldFoo = this.get('_oldFoo'); 

    if (foo === oldFoo) { return; } 

    // Do stuff here 

    this.set('_oldFoo', foo); 
}) 
+0

come fa questo osservatore a sapere quando essere licenziato quando non ha alcuna proprietà a cui si abbona? Ho provato qualcosa di simile con .observes ('foo') e il valore di foo era già cambiato all'interno della funzione observer. –

+0

Thx, ho aggiornato la mia risposta con la chiave di dipendenza. Sì, il valore dipendente è nuovo nell'osservatore. Si confronta con il valore precedente e se è diverso da quello che si sa che il valore è cambiato. –

+0

OK, ho capito, grazie per i chiarimenti e l'aggiornamento. Nel mio caso, in realtà stavo usando il vecchio valore per impostare il nuovo valore se il nuovo valore non era definito, quindi usare il setter era il migliore perché allora non avevo bisogno di scomporre il valore. Ma vedo che funziona molto bene in molti casi. –

0

ho usato una proprietà calcolata per indirizzare alla proprietà di un modello e di memorizzare l'ultimo valore al momento della sua serie.

registrationGroup: Em.computed('regionModel.registrationGroup', 
get:-> 
    @.get('regionModel.registrationGroup') 
set:(key, value, oldValue)-> 
    @.set('lastRegistrationGroup', oldValue) 
    @.set('regionModel.registrationGroup', value) 
) 
+0

Non hai bisogno di un punto dopo '@' in CoffeeScript. Per esempio. '@get()'. –

+0

Inoltre, perché stai usando un getter? Stai proteggendo contro riscrittura? –

+0

Io uso i punti in CS perché trovo più facile cercare determinate chiamate con loro, e trovo anche che migliora la leggibilità. Ottieni solo coerenza, così posso usare la stessa proprietà per ottenere e impostare. –

Problemi correlati