Создание и регистрация сервисов

В Ember.js сервисы играют ключевую роль в централизованном управлении состоянием и логикой приложения. Сервисы могут хранить данные, обрабатывать бизнес-логику и быть доступны для использования в разных частях приложения. В этой главе рассмотрены основные принципы создания и регистрации сервисов в Ember.js.

Что такое сервисы?

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

Сервисы часто используются для:

  • Сохранения глобального состояния приложения, например, текущего пользователя, настроек или темы оформления.
  • Реализации логики, которая должна быть доступна на протяжении всего жизненного цикла приложения, такой как обработка аутентификации или подключение к внешним API.
  • Централизации кода, который может быть переиспользован в различных частях приложения.

Создание сервисов

В Ember.js создание сервиса — это процесс, состоящий из двух этапов: создания самого сервиса и его регистрации в системе.

Для создания сервиса используется команда генератора:

ember generate service имя_сервиса

Эта команда создаст файл в директории app/services/, где будет храниться код сервиса. Пример:

app/
  services/
    user.js

Внутри файла сервиса создается класс, который расширяет Service:

// app/services/user.js
import Service from '@ember/service';

export default class UserService extends Service {
  user = null;

  setUser(userData) {
    this.user = userData;
  }

  getUser() {
    return this.user;
  }
}

В приведенном примере создается сервис, который управляет состоянием объекта пользователя. В нем определены методы для получения и установки данных пользователя.

Регистрация сервисов

В Ember.js сервисы автоматически регистрируются и становятся доступными в приложении благодаря встроенной системе внедрения зависимостей. Это означает, что сервис не нужно вручную регистрировать в контейнере зависимостей — достаточно создать файл сервиса в соответствующей директории, и Ember сделает его доступным.

Сервисы доступны в любом компоненте, контроллере или маршруте с помощью механизма инъекции зависимостей. Чтобы внедрить сервис, используется декоратор @service:

// app/controllers/application.js
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';

export default class ApplicationController extends Controller {
  @service user;
  
  get userName() {
    return this.user.getUser()?.name || 'Гость';
  }
}

В этом примере сервис user инжектируется в контроллер application, и его методы могут быть использованы для получения данных пользователя.

Инъекция сервисов

Сервисы можно внедрять не только в контроллеры, но и в компоненты, маршруты и другие части приложения. Для этого используется декоратор @service, который автоматически связывает сервис с компонентом или маршрутом.

Пример инъекции сервиса в компонент:

// app/components/user-profile.js
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';

export default class UserProfileComponent extends Component {
  @service user;

  get userName() {
    return this.user.getUser()?.name || 'Неизвестный';
  }
}

В этом примере компонент user-profile использует сервис user, чтобы вывести имя текущего пользователя. Использование @service позволяет легко интегрировать сервисы в любую часть приложения.

Ленивая загрузка сервисов

Ember.js использует ленивую загрузку для сервисов, что означает, что сервис будет создан и инициализирован только в тот момент, когда он впервые потребуется. Это позволяет оптимизировать загрузку приложения и снижать нагрузку на начальную загрузку.

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

Синглтоны

Сервисы в Ember.js являются синглтонами. Это означает, что на протяжении всей жизни приложения будет существовать только один экземпляр сервиса. Это гарантирует, что данные и состояние сервиса будут общими для всех компонентов и контроллеров, использующих данный сервис.

Синглтон — это один из ключевых аспектов, который отличает сервисы от других объектов в Ember.js. Когда сервис инжектируется в компонент или контроллер, все они работают с одним и тем же экземпляром, что позволяет легко обмениваться данными и управлять состоянием.

Сервис как хранилище состояния

Сервисы в Ember.js часто используются как хранилища для состояния, которое должно быть доступно во всех частях приложения. Например, можно использовать сервис для управления состоянием аутентификации пользователя или хранения текущих настроек приложения.

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

// app/services/auth.js
import Service from '@ember/service';

export default class AuthService extends Service {
  isAuthenticated = false;

  authenticate(credentials) {
    // Логика аутентификации
    if (credentials.username === 'admin' && credentials.password === '1234') {
      this.isAuthenticated = true;
    }
  }

  logout() {
    this.isAuthenticated = false;
  }

  getAuthenticationStatus() {
    return this.isAuthenticated;
  }
}

Этот сервис может быть использован в разных компонентах и контроллерах для проверки аутентификации пользователя и выполнения соответствующих действий.

Деструктуризация сервисов

Если необходимо использовать только определенные методы или свойства сервиса, можно выполнить деструктуризацию при инъекции, что сделает код более компактным и понятным.

Пример деструктуризации сервиса:

// app/components/user-profile.js
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';

export default class UserProfileComponent extends Component {
  @service('user') userService;

  get userName() {
    const { user } = this.userService;
    return user?.name || 'Неизвестный';
  }
}

В этом примере используется деструктуризация для получения объекта user из сервиса userService, что позволяет упростить доступ к его свойствам.

Заключение

Сервисы в Ember.js являются мощным инструментом для управления состоянием и логикой приложения. Они предоставляют централизованную возможность взаимодействия с данными, которые могут быть использованы в различных частях приложения. Благодаря механизму внедрения зависимостей, работа с сервисами становится простой и удобной, позволяя легко разделить логику и состояния по всему приложению.