Ember.js:我如何确定观察者中的属性是否真的发生了变化?

时间:2014-05-18 01:08:59

标签: ember.js

假设我有Article s支持Source s。每篇文章都有一个来源。

来源已关联HTML,将在屏幕上呈现。

如果源更改,我希望此HTML仅呈现

App.ArticleView = Ember.View.extend({
  didInsertElement: function() {
    this.addObserver('controller.source.id', function() {
      console.log(arguments);
      renderHTML();
    });
  });
});

这与陈述in the addObserver documentation的行为完全相同,“请注意,无论是否实际更改了值,都会在设置值时触发观察者。您的观察者应该准备好处理它。”

如果设置controller.model Article A来源1,则设置controller.model Article B使用来源1,观察者会调用该方法但我想阻止renderHTML()发生

文档中提到了“观察者方法”,我不确定如何在这种情况下使用。它的签名(function(sender, key, value, rev) { };)看起来完全像我需要的那样,但在我的测试中,观察者方法的arguments总是0: (current view), 1: "controller.source.id"

如何获取controller.source.id的先前值,以确定是否renderHTML()

1 个答案:

答案 0 :(得分:1)

Ember.set如果与当前值相同,则不会设置该值,因此除非值发生变化,否则您的观察者不会开火。

以下是一个例子:

http://emberjs.jsbin.com/jiyesuzi/2/edit

此处Ember.set中的代码执行此操作(https://github.com/emberjs/ember.js/blob/master/packages_es6/ember-metal/lib/property_set.js#L73

// only trigger a change if the value has changed
  if (value !== currentValue) {
    Ember.propertyWillChange(obj, keyName);
    if (MANDATORY_SETTER) {
      if ((currentValue === undefined && !(keyName in obj)) || !obj.propertyIsEnumerable(keyName)) {
        Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
      } else {
        meta.values[keyName] = value;
      }
    } else {
      obj[keyName] = value;
    }
    Ember.propertyDidChange(obj, keyName);
  }

不幸的是,对于你的情况,Ember考虑改变链的一部分作为改变项目,即如果controller.source改变,那么观察者将会发射。您需要以不同方式跟踪您的身份,以避免您的观察者被解雇。您可以创建一个始终在本地属性上设置当前id的不同观察者,然后在链断开时不会触发更新。

控制器内部

currentArticleId: null,

watchArticle: function(){
  this.set('currentArticleId', this.get('article.id'));
}.observes('article.id')

然后你会看controller.currentArticleId