Введение в сервисы и внедрение зависимостей
Сервис - это широкая категория, охватывающая любое значение, функцию или функцию, которая необходима приложению. Служба обычно представляет собой класс с узкой, четко определенной целью. Он должен делать что-то конкретное и делать это хорошо.
Angular отличает компоненты от сервисов для повышения модульности и возможности повторного использования. Отделяя функциональность компонента, связанную с представлением, от других видов обработки, вы можете сделать свои классы компонентов экономичными и эффективными.
В идеале, работа компонента заключается в обеспечении взаимодействия с пользователем и ничего более. Компонент должен представлять свойства и методы для привязки данных, чтобы обеспечить связь между представлением (отображаемым шаблоном) и логикой приложения (которая часто включает в себя некоторое представление о модели ).
В идеале, работа компонента заключается в обеспечении взаимодействия с пользователем и ничего более. Компонент должен представлять свойства и методы для привязки данных, чтобы обеспечить связь между представлением (отображаемым шаблоном) и логикой приложения (которая часто включает в себя некоторое представление о модели ).
Компонент может делегировать определенные задачи службам, такие как выборка данных с сервера, проверка ввода данных пользователем или ведение журнала непосредственно на консоль. Определив такие задачи обработки в классе обслуживания для инъекций , вы сделаете эти задачи доступными для любого компонента. Вы также можете сделать свое приложение более адаптируемым, вводя различным поставщикам один и тот же вид услуг, в зависимости от обстоятельств.
Angular не применяет эти принципы. Angular помогает вам следовать этим принципам, упрощая разделение логики вашего приложения на сервисы и делая эти сервисы доступными для компонентов посредством внедрения зависимостей .
Сервисные примеры
Вот пример класса обслуживания, который регистрируется в консоли браузера.
Код TypeScript:
export class Logger {
log(msg: any){ console.log(msg); }
error(msg:any){ console.error(msg); }
warn(msg:any){ console.warn(msg); }
}
Демонстрация в реальном времени:
Смотрите Pen Пример класса обслуживания в Angular от w3resource ( @ w3resource ) на CodePen .
Услуги могут зависеть от других услуг. Например, вот HeroService, который зависит от службы Logger, а также использует BackendService для получения героев. Эта служба, в свою очередь, может зависеть от службы HttpClient для асинхронной выборки героев с сервера.
Код TypeScript:
export class HeroService {
private heroes: Hero[] = [];
constructor(
private backend: BackendService,
private logger: Logger) { }
getHeroes() {
this.backend.getAll(Hero).then( (heroes: Hero[]) => {
this.logger.log(`Fetched ${heroes.length} heroes.`);
this.heroes.push(...heroes); // fill cache
});
return this.heroes;
}
}
Демонстрация в реальном времени:
См. Перо, иллюстрирующее зависимость класса обслуживания в Angular от w3resource ( @ w3resource ) от CodePen .
Инъекция зависимости (DI)
DI встроен в платформу Angular и используется повсеместно для предоставления новым компонентам услуг или других необходимых им вещей. Компоненты потребляют услуги; то есть вы можете внедрить сервис в компонент, предоставляя компоненту доступ к этому классу сервиса.
Чтобы определить класс как службу в Angular, используйте декоратор @Injectable () для предоставления метаданных, которые позволяют Angular внедрять его в компонент в качестве зависимости. Аналогично, используйте декоратор @Injectable (), чтобы указать, что компонент или другой класс (например, другой сервис, канал или модуль NgModule) имеет зависимость.
Инжектор является основным механизмом. Angular создает инжектор для всего приложения во время процесса начальной загрузки и дополнительные инжекторы по мере необходимости. Вам не нужно создавать инжекторы.
Инъектор создает зависимости и поддерживает контейнер экземпляров зависимостей, который он использует, если это возможно.
Поставщик - это объект, который сообщает инжектору, как получить или создать зависимость.
Для любой зависимости, которая вам нужна в вашем приложении, вы должны зарегистрировать поставщика с помощью инжектора приложения, чтобы инжектор мог использовать поставщика для создания новых экземпляров. Для службы поставщиком обычно является сам класс обслуживания.
Зависимость не обязательно должна быть службой - это может быть, например, функция или значение.
Когда Angular создает новый экземпляр класса компонента, он определяет, какие службы или другие зависимости нужны компоненту, просматривая типы параметров конструктора. Например, конструктор HeroListComponent нуждается в HeroService.
Код TypeScript:
constructor(private service: HeroService) { }
Демонстрация в реальном времени:
См. Пример пера конструктора от w3resource ( @ w3resource ) в CodePen .
Когда Angular обнаруживает, что компонент зависит от службы, он сначала проверяет, есть ли у инжектора какие-либо существующие экземпляры этой службы. Если запрошенный экземпляр службы еще не существует, инжектор создает его с использованием зарегистрированного поставщика и добавляет его к инжектору перед возвратом службы в Angular.
Когда все запрошенные сервисы разрешены и возвращены, Angular может вызвать конструктор компонента с этими сервисами в качестве аргументов.
Предоставление услуг
Вы должны зарегистрировать хотя бы одного поставщика любой услуги, которую вы собираетесь использовать. Поставщик может быть частью собственных метаданных службы, делая эту службу доступной повсеместно, или вы можете зарегистрировать поставщиков с помощью определенных модулей или компонентов. Вы регистрируете поставщиков в метаданных службы (в декораторе @Injectable ()) или в метаданных @NgModule () или @Component ().
По умолчанию команда Angular CLI ng generate service регистрирует поставщика с корневым инжектором для вашей службы, включая метаданные поставщика в декоратор @Injectable (). Учебное пособие использует этот метод для регистрации поставщика определения класса HeroService.
Код TypeScript:
@Injectable({
providedIn: 'root',
})
Демонстрация в реальном времени:
См. Раздел « Регистрация пером» поставщика по w3resource ( @ w3resource ) на CodePen .
Когда вы предоставляете сервис на корневом уровне, Angular создает один общий экземпляр HeroService и внедряет его в любой класс, который его запрашивает. Регистрация провайдера в метаданных @Injectable () также позволяет Angular оптимизировать приложение, удаляя службу из скомпилированного приложения, если оно не используется.
Когда вы регистрируете провайдера с определенным NgModule, один и тот же экземпляр сервиса становится доступным для всех компонентов в этом NgModule. Чтобы зарегистрироваться на этом уровне, используйте свойство провайдеров декоратора @NgModule (),
Код TypeScript:
@NgModule({
providers: [
BackendService,
Logger
],
...
})
Демонстрация в реальном времени:
См. Перо « Регистрация провайдера с определенным модулем NgModule» с помощью w3resource ( @ w3resource ) в CodePen .
Когда вы регистрируете поставщика на уровне компонента, вы получаете новый экземпляр службы с каждым новым экземпляром этого компонента. На уровне компонента зарегистрируйте поставщика услуг в свойстве поставщиков метаданных @Component ().
Код TypeScript:
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
providers: [ HeroService ]
})
Демонстрация в реальном времени:
См. Перо « Регистрация провайдера на уровне компонентов» с помощью w3resource ( @ w3resource ) в CodePen .
Предыдущая: Обзор архитектуры
Далее: Введение в компоненты
Новый контент: Composer: менеджер зависимостей для PHP , R программирования