Ember.js предоставляет мощные инструменты для работы с состоянием приложения, и один из таких инструментов — Observers. В Ember, observers позволяют следить за изменениями свойств и реагировать на них. Это особенно полезно в динамических интерфейсах, где состояние компонента или модели зависит от других значений.
Observer — это механизм, который позволяет отслеживать изменения значений свойств и выполнять код, когда это свойство изменяется. Этот механизм можно использовать для выполнения логики, которая зависит от состояния других свойств.
Пример простого Observer’а:
import Ember from 'ember';
export default Ember.Component.extend({
firstName: '',
lastName: '',
fullNameChanged: Ember.observer('firstName', 'lastName', function() {
const firstName = this.get('firstName');
const lastName = this.get('lastName');
this.set('fullName', `${firstName} ${lastName}`);
})
});
В этом примере свойство fullName автоматически
обновляется всякий раз, когда меняются firstName или
lastName. Это достигается благодаря observer’у, который
отслеживает изменения этих свойств и обновляет
fullName.
Observer создается с использованием функции
Ember.observer, которая принимает список зависимых свойств
(строк) и функцию, которая будет вызвана при их изменении. В этой
функции можно написать код для обновления состояния компонента или
выполнения другой логики.
Ember.observer('property1', 'property2', function() {
// Действия, выполняемые при изменении property1 или property2
});
Важно заметить, что в этой функции мы можем обращаться к значениям
свойств через this.get('propertyName') и изменять их с
помощью this.set('propertyName', newValue).
Когда мы указываем несколько зависимостей в observer’е, все эти свойства будут отслеживаться. Если хотя бы одно из них изменится, observer будет вызван. Например:
fullNameChanged: Ember.observer('firstName', 'lastName', function() {
// Код, который будет выполнен при изменении firstName или lastName
});
В случае, если нужно отслеживать изменения большого количества свойств, можно передать их в observer как список, но в этом случае важно быть внимательным к производительности. Если свойств слишком много, это может негативно сказаться на производительности, особенно при частых изменениях состояния.
Observer срабатывает только в том случае, если значение свойства реально изменилось. Это важно учитывать, когда работаете с вычисляемыми свойствами или пытаетесь изменить значения, которые могут быть равны текущим значениям. Ember будет отслеживать изменения и срабатывать только при реальном изменении, а не при установке того же самого значения.
Если свойство, за которым вы следите с помощью observer’а, является вычисляемым (computed property), важно понимать, что оно будет отслеживаться на основе его зависимости от других свойств. Ember сам будет отслеживать изменения зависимых значений, обновляя вычисляемое свойство, и observer сработает, когда это свойство изменится.
Пример:
import Ember from 'ember';
export default Ember.Component.extend({
firstName: '',
lastName: '',
fullName: Ember.computed('firstName', 'lastName', function() {
return `${this.get('firstName')} ${this.get('lastName')}`;
}),
fullNameChanged: Ember.observer('fullName', function() {
console.log('Full name has changed:', this.get('fullName'));
})
});
Здесь свойство fullName будет обновляться автоматически
при изменении firstName или lastName, и
observer сработает каждый раз, когда fullName
изменится.
С помощью observer’ов можно организовать мощную реактивную модель, но необходимо помнить о потенциальных проблемах с производительностью. Каждый раз, когда изменяется одно из отслеживаемых свойств, observer будет запускаться. Если количество таких изменений велико, или если свойства часто меняются, это может повлиять на производительность приложения.
Чтобы избежать ненужных срабатываний observer’ов, рекомендуется:
В некоторых случаях использование observer’ов может быть избыточным,
и есть альтернативные способы реактивного обновления состояния в Ember.
Одним из таких способов является использование computed
properties и actions. Особенно в новых версиях
Ember многие задачи, ранее решавшиеся через observer’ы, теперь могут
быть решены через @tracked и computed-свойства в рамках
компонентов или классов.
Пример с использованием @tracked:
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
export default class FullNameComponent extends Component {
@tracked firstName = '';
@tracked lastName = '';
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
Здесь использование @tracked позволяет отслеживать
изменения свойств firstName и lastName без
явного использования observer’ов.
Ember.js предоставляет Observer’ы как один из инструментов для работы
с состоянием, позволяя отслеживать изменения свойств и выполнять
действия в ответ на эти изменения. Однако, несмотря на их полезность,
следует учитывать их влияние на производительность и использовать их
только в тех случаях, когда это действительно необходимо. С развитием
фреймворка появилось больше альтернативных методов работы с состоянием,
таких как @tracked и вычисляемые свойства, которые могут
быть более эффективными для современных приложений.