Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can an observer find out the before and after values of the observed property in Ember.js?

Tags:

ember.js

Please see the solution to another question provided by ud3323: http://jsfiddle.net/ud3323/ykL69/. This solution highlights the changed value using the red color. I have an additional requirement: if the value has increased highlight in green color, if it has decreased highlight in red color. For this, I need to know the old and the new values in my observer. Is there any way to do this?

P.S. Embers docs do not say anything about what's available in the observer function. All I can tell from the example is that since the observer is defined in the itemRowView, "this" points to the itemRowView.

like image 994
Naresh Avatar asked Feb 10 '12 21:02

Naresh


3 Answers

beforeObserver has been deprecated in Ember 1.10.

Instead, use a manual cache:

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);
})
like image 182
Andrey Mikhaylov - lolmaus Avatar answered Nov 16 '22 08:11

Andrey Mikhaylov - lolmaus


Take a look at beforeObservers. A beforeObserver fires before a property changes. So if you get the property in a beforeObserver, you will have the the pre-change value. You set up this type of observer using Ember.addBeforeObserver or via the observesBefore function prototype extension.

That would give you what you need to achieve your goal. I've created the following JSBin based on your fiddle to demonstrate this here: http://emberjs.jsbin.com/qewudu/2/edit

UPDATED on 2014-10-07 to reflect behavior in Ember 1.7.x.

UPDATE on 2015-02: beforeObserver has been deprecated. See other answers to this question.

like image 12
Luke Melia Avatar answered Nov 16 '22 07:11

Luke Melia


Use willInsertElement to store the initial value, and upon change of the value, compare the two:

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

Take a look at the jsfiddle http://jsfiddle.net/ykL69/15/

like image 2
Panagiotis Panagi Avatar answered Nov 16 '22 07:11

Panagiotis Panagi