May 09, 2021 Ember.js Reference documents
Ember
detect changes in any property, including calculated properties.
Ember
aware of changes in all attributes, including calculated properties. O
bservers are useful, especially if synchronization is required after calculating property bindings. O
bservers are often overused by Ember.
Ember
framework itself is already heavily used by observers, but it is a more appropriate solution for most developers to use compute attributes in the face of development problems.
How to use:
Ember.observer
to create an object as an observer.
// Observer对于Emberjs来说非常重要,前面你看到的很多代码都是与它有关系,计算属性之所以能更新也是因为它
Person = Ember.Object.extend({
firstName: null,
lastName: null,
fullName: Ember.computed('firstName', 'lastName', function() {
return this.get('firstName') + " " + this.get('lastName');
}),
// 当fullName被改变的时候触发观察者
fullNameChange: Ember.observer('fullName', function() {
console.log("The fullName is changed by caller");
//return this.get('fullName');
})
});
var person = Person.create({
firstName: 'chen',
lastName: 'ubuntuvim'
});
// 如果被观察的计算属性还没执行过get()方法不会触发观察者
console.log('fullName = ' + person.get('fullName'));
// fullName是依赖firstName和lastName的,这里改变了firstName的值,计算属性会自动更新,
// fullName被改变了所以会触发观察者
person.set('firstName', 'change firstName value'); // 观察者会被触发
console.log('fullName = ' + person.get('fullName'));
fullName
firstName
lastName
and the
set()
firstName
which naturally causes
fullName
to change,
fullName
to trigger the observer.
As can be seen from the results of implementation;
Ember
provides developers with another way to use observers.
This way you can add an observer to a calculated property outside of the class definition.
person.addObserver('fullName', function() {
// deal with the change…
});
Currently, observers
Ember
in Ember (either by mistake, as the official website says by
Observers in Ember are currently synchronous.
)
。 T
his means that as soon as the calculated property changes, the observer is triggered. I
t is also easy to introduce such bugs when
bug
are not synchronized.
For example, the following code;
Person.reopen({
lastNameChanged: Ember.observer('lastName', function() {
// The observer depends on lastName and so does fullName. Because observers
// are synchronous, when this function is called the value of fullName is
// not updated yet so this will log the old value of fullName
console.log(this.get('fullName'));
})
});
However, for synchronization reasons, if your observer observes multiple properties at the same time, it causes the observer to perform multiple times.
person = Ember.Object.extend({
firstName: null,
lastName: null,
fullName: Ember.computed('firstName', 'lastName', function() {
return this.get('firstName') + " " + this.get('lastName');
}),
// 当fullName被改变的时候触发观察者
fullNameChange: Ember.observer('fullName', function() {
console.log("The fullName is changed by caller");
//return this.get('fullName');
})
});
Person.reopen({
partOfNameChanged: Ember.observer('firstName', 'lastName', function() {
// 同时观察了firstName和lastName两个属性
console.log('========partOfNameChanged======');
})
});
var person = Person.create({
firstName: 'chen',
lastName: 'ubuntuvim'
});
person.set('firstName', '[firstName]');
person.set('lastName', '[lastName]');
Obviously the above code executes
set()
so the observer will also execute twice, but what if you need to set up in development to perform only one observation?
Ember provides a
once()
method that executes the next time all the binding properties in the loop are synchronized.
Person = Ember.Object.extend({
firstName: null,
lastName: null,
fullName: Ember.computed('firstName', 'lastName', function() {
return this.get('firstName') + " " + this.get('lastName');
}),
// 当fullName被改变的时候触发观察者
fullNameChange: Ember.observer('fullName', function() {
console.log("The fullName is changed by caller");
//return this.get('fullName');
})
});
Person.reopen({
partOfNameChanged: Ember.observer('firstName', 'lastName', function() {
// 同时观察了firstName和lastName两个属性
// 方法partOfNameChanged本身还是会执行多次,但是方法processFullName只会执行一次
console.log('========partOfNameChanged======'); //
Ember.run.once(this, 'processFullName');
}),
processFullName: Ember.observer('fullName', function() {
// 当你同时设置多个属性的时候,此观察者只会执行一次,并且是发生在下一次所有属性都被同步的时候
console.log('fullName = ' + this.get('fullName'));
})
});
var person = Person.create({
firstName: 'chen',
lastName: 'ubuntuvim'
});
person.set('firstName', '[firstName]');
person.set('lastName', '[lastName]');
The observer does not execute until the object initialization is complete. I
f you want the observer to execute when the object is initialized, you must manually
Ember.on()
method.
This method is executed after the object is initialized.
Person = Ember.Object.extend({
salutation:null,
init() {
this.set('salutation', 'hello');
console.log('init....');
},
salutationDidChange: Ember.on('init', Ember.observer('salutation', function() {
console.log('salutationDidChange......');
}))
});
var p = Person.create();
p.get('salutationDidChange'); // output > init.... salutationDidChange......
console.log(p.get('salutation')); // output > hello
p.set('salutation'); // output > salutationDidChange......
If a calculated property never calls its
get()
the observer is not triggered, even if the value of the calculated property changes. Y
ou can argue that the observer determines whether the
get()
has changed based on a comparison of values before and after calling the get() method. I
f you haven't
get()
change observer thinks there is no change. U
sually we don't have to worry about this affecting the program code, because almost all of the observed compute properties perform value-taking operations before they are triggered. I
f you're still worried that the observer won't be
init()
a get operation in the
get
method. T
his is sufficient to ensure that your observations were geodesy before they were triggered.
For beginners, the automatic update of property values is still a bit difficult to understand, in the end how it is an update method!!! D
on't worry, let's put it first, and as you learn more, you'll learn how powerful this is.
The full code of the blog post
is placed in Github
(the blog post has been modified several times, and the code on the blog post may be different from the github code, but the impact is small!). I
f you think the blog post is a bit of a github project for you, give me
star
Yours is definitely the biggest motivation for me!!