2012-02-10 88 views
24

请参阅由ud3323提供的另一个问题的解决方案:http://jsfiddle.net/ud3323/ykL69/。该解决方案使用红色突出显示更改的值。我有一个额外的要求:如果值增加了绿色的高光,如果它减少了红色的高光。为此,我需要了解观察者的新旧价值观。有没有办法做到这一点?观察者如何才能找出Ember.js中被观察属性的前后值?

P.S.余烬文档没有说明观察者函数中可用的内容。我从例子中可以看出,由于观察者是在itemRowView中定义的,“this”指向itemRowView。

回答

12

看看beforeObserver秒。 A beforeObserver在物业更改前发生火灾。因此,如果您在beforeObserver中的属性为get,那么您将拥有预先更改的值。您使用Ember.addBeforeObserver或通过observesBefore函数原型扩展来设置此类型的观察者。

这会给你你需要什么来实现你的目标。我已经创建了以下JSBin基于您的小提琴来演示此处:http://emberjs.jsbin.com/qewudu/2/edit

更新于2014-10-07以反映Ember 1.7.x中的行为。

2015-02更新:beforeObserver已被弃用。请参阅此问题的其他解答。

+0

Ember.addBeforeObserver更清洁。谢谢卢克! – Naresh 2012-02-11 06:18:06

+11

顺便说一句,我最近注意到有一个'observesBefore'函数的扩展,所以代码可以做得更好,因为在http://jsfiddle.net/ye3M2/ – 2012-02-14 21:24:58

+3

我不相信'价值'正在提供。我正在版本1.5.1中测试 – Denzo 2014-05-21 01:18:48

2

使用willInsertElement存储初始值,并且在价值的变化,比较两个:

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

看看的的jsfiddle http://jsfiddle.net/ykL69/15/

+0

谢谢扎克。这很好。但是,如果我的理解是正确的,则此代码中有一个错误。看起来,willInsertElement()仅被调用一次(最初插入元素时)。因此,为了保持颜色正确显示,在valueDidChange()的末尾,您必须将initialValue重新初始化为新值 - 从而确保将下一个更改与此值进行比较。虽然这种方法总体上起作用,但该观点现在正成为缓冲价值的地方。相反,如果观察者可以提供旧的和新的价值,代码可以更简单。 – Naresh 2012-02-11 00:49:45

+0

更正了我的答案。正如@Luke所说,它看起来像beforeObserver可以达到同样的结果。 – 2012-02-11 05:36:50

+0

我同意。谢谢。 – Naresh 2012-02-11 06:18:33

16

beforeObserver已经在Ember 1.10中的deprecated

相反,使用手动缓存:

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

这个观察者如何知道何时在没有任何属性的情况下被触发?我尝试了一些与.observes('foo')类似的东西,并且foo值已经在观察者函数内部改变了。 – 2015-09-09 16:43:14

+0

Thx,我用依赖关键码更新了我的答案。是的,相关的值在观察者中是新的。您将它与以前的值进行比较,如果它不同于您知道值已更改。 – 2015-09-09 16:45:54

+0

好的,我明白了,谢谢澄清和更新。在我的情况下,如果新值未定义,我实际上是使用旧值来设置新值,所以使用setter是最好的,因为那样我就不需要隐藏值了。但是我发现这在很多情况下都很有效。 – 2015-09-09 20:01:31

0

我用了一个计算的属性路由到一个模型的属性,并存储在其设定的最后一个值。

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

CoffeeScript中的@ @后不需要点。例如, '@get()'。 – 2015-09-09 16:47:05

+0

另外,你为什么使用getter?你是否保护不重写? – 2015-09-09 16:47:49

+0

我在CS中使用点,因为我发现用它们搜索某些调用比较容易,而且我还发现它提高了可读性。 Getter只是为了保持一致性,所以我可以使用相同的属性来获取和设置。 – 2015-09-09 19:57:30