【问题标题】:How do I get the BeforeObserver equivalent in Ember 2.3?如何在 Ember 2.3 中获得等效的 BeforeObserver?
【发布时间】:2016-05-22 23:08:06
【问题描述】:

首先,我必须澄清一下,在过渡到 Ember 2.3 的过渡期间,我正在使用 legacy-controller 和 legacy-view,可在此处找到:

https://github.com/emberjs/ember-legacy-controllers

现在,我的(旧版)控制器上有一个名为 currentTopPost 的属性。

在 Ember 1.7 中,我有这样的设置:

// before observer
currentTopPostBeforeObserver: function(){
...
}.observesBefore('currentTopPost'),

// observer
currentTopPostBeforeObserver: function(){
...
}.observes('currentTopPost'),

我这样做的原因是,当 currentTopPost 更改时,我希望它在将其值切换到新属性之前保存旧的 topPost,因为它是一个 Post 对象(我有一个 Post 模型)。

当然,在 1.7 中,我将旧帖子保存在 beforeObserver 中,然后在观察者中执行我必须做的任何其他事情。现在,在 Ember 2.3 中,我进行了以下设置:

currentTopPostObserver: Ember.observer('currentTopPost', function(){
...

}),

就使用新值执行功能而言,这工作得很好。但是我已经失去了在值改变之前处理动作的能力。现在根据这个问题的答案:

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

observesBefore 函数已被弃用,我们应该遵循这个:

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

但是,在尝试使用 this.get("_oldCurrentTopPost") 时,我什么也没得到。如何在此属性更改之前访问它的旧值?

【问题讨论】:

    标签: ember.js ember.js-2


    【解决方案1】:

    据我所知,没有特别好的方法可以恢复该机制。在许多情况下,观察者本身“被认为是有害的”,但我会尽力为您提供实用的替代解决方案。

    我能想到的最好的快速且相对肮脏的方法是使用 getter 和 setter 创建一个“代理”计算属性。在设置器中,您可以获取“真实”属性的先前值,调用函数来执行任何操作,然后在真实属性上设置新值。

    这是一个您可以使用的示例:

    myProxyProperty: Ember.computed('myRealProperty', {
      get() {
        return this.get('myRealProperty');
      },
      set(key, value) {
        const oldValue = this.get('myRealProperty');
    
        this.doSomethingWithOldValue(oldValue);
    
        this.set('myRealProperty', oldValue);
      }
    })
    

    很遗憾,我目前不知道在新 Ember 中执行此操作的更好方法。

    【讨论】:

    • 我建议采用上述 Miguel 的方法,不过我将把它留在这里作为替代方案。
    • 我认为上面想做this.set('myRealProperty', value)。事实上,我认为它会保留旧值并且永远不会设置新值
    【解决方案2】:

    我使用的替代品是:

    propWillChange(prop) {
      //your new before observer
    },
    
    propDidChange: Ember.observer('prop', function() {
    
      let prop = this.get('prop');
    
      if (this._oldProp !== prop) {
        this.propWillChange(this._oldProp);
        this._oldProp = prop;
      }
    
      //Do stuff
    
    })
    

    当然,在第一次运行时,_oldProp 将是undefined,但这是意料之中的,对吧?这是第一次更改prop

    我也不同意不应该使用观察者。我同意应尽可能避免使用观察者,因为许多人并没有完全理解它们的副作用,但在许多情况下它们非常有用,尤其是在构建 3rd 方插件集成时。

    由于该问题专门询问了 beforeObserver 替换,因此在这里。但是,如果可能的话,我建议重新考虑是否可以在没有观察者的情况下重建您的用例。

    玩转:https://ember-twiddle.com/045b7b9c1562ceb6bbdc

    【讨论】:

    • 我应该使用“应尽可能避免”一词而不是“认为有害”,我也喜欢这种方法。
    • 我正在尝试实现这一点 - 顺便说一下,我喜欢这种方法 - 但我无法访问旧道具。我尝试过:this._oldProp、this._oldCurrentTopPost、this.get("_oldCurrentTopPost") 和 this.get("_oldProp")。我想我搞砸了命名约定或其他东西。我使用了观察到的属性的名称,在本例中为“currentTopPost”,并尝试在其中添加“旧”。此外,我已经测试了它从未定义到先选择,然后再选择第二个,但所有 'oldProp' 仍然未定义。
    • @Darshan 我已经用一个证明它有效的旋转更新了答案。我还更新了一些缺少的括号以关闭 observer 函数。
    • @Darshan 这有帮助吗?
    • @Darshan 这符合您的要求吗?可以接受吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多