假设我有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()
?
答案 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