Базовый класс Ember.Object

Ember.js предоставляет богатый набор инструментов для построения веб-приложений, и в его основе лежит объектно-ориентированная парадигма. Одним из важнейших элементов этой парадигмы является класс Ember.Object, который служит основой для создания объектов в Ember.js. Класс Ember.Object расширяет стандартные возможности JavaScript, предоставляя функциональность для работы с наблюдаемыми свойствами, жизненным циклом объектов и интеграцией с другими частями фреймворка.

Основные концепции

Ember.Object является базовым классом для всех объектов в Ember. В отличие от обычных JavaScript-объектов, объекты, наследующие от Ember.Object, могут работать с системой наблюдения и реагировать на изменения своих свойств. Это позволяет автоматизировать рендеринг и обновление UI, а также взаимодействовать с другими частями приложения.

Создание объекта

Для создания нового объекта на основе Ember.Object используется метод EmberObject.extend. Этот метод позволяет расширить базовый функционал, добавив свои свойства и методы.

Пример:

import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  firstName: '',
  lastName: '',
  
  fullName: Ember.computed('firstName', 'lastName', function() {
    return `${this.firstName} ${this.lastName}`;
  })
});

let person = Person.create({
  firstName: 'Иван',
  lastName: 'Иванов'
});

console.log(person.fullName); // "Иван Иванов"

В этом примере создается объект Person, который содержит два свойства — firstName и lastName, а также вычисляемое свойство fullName, которое зависит от других свойств. При изменении этих свойств, Ember автоматически пересчитывает значение fullName и обновляет UI.

Наблюдаемые свойства

Одним из ключевых аспектов Ember.Object является возможность работать с наблюдаемыми свойствами. С помощью декоратора @observable или Ember.observable можно создать свойства, которые отслеживаются системой и автоматически обновляются, если их значения изменяются.

Пример:

import EmberObject, { tracked } from '@ember/object';

const Product = EmberObject.extend({
  @tracked price: 100,
  @tracked discount: 10,
  
  @computed('price', 'discount')
  get finalPrice() {
    return this.price - this.discount;
  }
});

let product = Product.create();
console.log(product.finalPrice); // 90

В этом примере используется декоратор @tracked, чтобы указать, что свойства price и discount должны быть отслеживаемыми. Когда одно из этих свойств изменится, Ember автоматически пересчитает значение finalPrice.

Методы жизненного цикла

Каждый объект, созданный на основе Ember.Object, имеет свой жизненный цикл. Важно понимать, когда происходят определенные события, такие как инициализация объекта или его удаление. Ember предоставляет несколько встроенных методов для работы с жизненным циклом объектов.

  • init(): Этот метод вызывается при создании нового экземпляра объекта. Он используется для инициализации свойств объекта.
  • willDestroy(): Этот метод вызывается перед удалением объекта. Он полезен для очистки ресурсов или выполнения других завершающих операций.
  • didInsertElement(): Метод вызывается, когда объект вставлен в DOM.

Пример использования методов жизненного цикла:

import EmberObject from '@ember/object';

const Car = EmberObject.extend({
  init() {
    this._super(...arguments);
    this.isRunning = false;
  },
  
  start() {
    this.isRunning = true;
    console.log('Машина заведена');
  },
  
  stop() {
    this.isRunning = false;
    console.log('Машина выключена');
  },
  
  willDestroy() {
    console.log('Машина уничтожена');
  }
});

let car = Car.create();
car.start();
car.stop();
car.willDestroy();

Здесь метод init используется для инициализации переменной isRunning, а метод willDestroy выводит сообщение перед уничтожением объекта.

Методы и вычисляемые свойства

Кроме обычных свойств, Ember позволяет создавать вычисляемые свойства, которые зависят от других свойств. Для этого используются специальные методы, такие как Ember.computed. Эти свойства автоматически пересчитываются при изменении зависимостей.

Пример:

import EmberObject from '@ember/object';
import { computed } from '@ember/object';

const Employee = EmberObject.extend({
  firstName: 'Иван',
  lastName: 'Иванов',

  fullName: computed('firstName', 'lastName', function() {
    return `${this.firstName} ${this.lastName}`;
  })
});

let employee = Employee.create();
console.log(employee.fullName); // "Иван Иванов"

В этом примере свойство fullName зависит от свойств firstName и lastName. Когда одно из этих свойств изменится, fullName будет автоматически пересчитано.

Использование Ember.Object в реальных приложениях

Ember.Object используется во многих частях приложений Ember, включая модели, контроллеры и компоненты. Каждый из этих элементов может наследовать от Ember.Object и использовать его функциональность.

  • Модели: В Ember.js модели часто наследуют от Ember.Object, чтобы получить доступ к системе наблюдения и обработки данных.
  • Контроллеры: Контроллеры управляют состоянием и данными в приложении, и они также могут быть объектами, расширяющими Ember.Object.
  • Компоненты: Компоненты в Ember.js могут использовать Ember.Object для хранения состояния и выполнения логики, связанной с отображением.

Пример использования модели с Ember.Object:

import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  firstName: '',
  lastName: '',

  fullName: computed('firstName', 'lastName', function() {
    return `${this.firstName} ${this.lastName}`;
  })
});

let person = Person.create({
  firstName: 'Дмитрий',
  lastName: 'Петров'
});

console.log(person.fullName); // "Дмитрий Петров"

Заключение

Класс Ember.Object представляет собой основу для создания объектов в Ember.js. Он расширяет стандартные объекты JavaScript, добавляя поддержку наблюдаемых свойств, вычисляемых значений и управления жизненным циклом. Это позволяет создавать гибкие и динамичные приложения, в которых данные и UI автоматически синхронизируются друг с другом.