От автора: в этой статье будет описан обычный сценарий использования некоторых библиотек, которые не имеют интеграции с Angular. В качестве примера я буду использовать библиотеку HashWords, конвертирующую хеш-строки в рандомные слова, читабельные для человека. Если вам лень читать статью, можете зайти на Github repo и ознакомиться с примерами кода.
Прежде всего, сторонняя библиотека должна быть установлена, для этого выполняем: $ npm install —save hashwords
Импортируем её в .angular-cli.json:
"scripts": ["../node_modules/hashwords/dist/hashwords.min.js"]
Благодаря последнему действию мы сделали её доступной в объекте window. Теперь можно зарегистрировать это в свойстве providers NgModule
providers: [ { provide: 'Hashwords', useValue: window['hashwords']() } ]
Предоставьте приложению Value window[‘hashwords’]() для любых включений, вызываемых Hashwords! Далее нам нужно добавить это новое значение в конструктор app.component.ts
import { Component, Inject } from '@angular/core'; import { ApiService } from './api.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { constructor( @Inject('Hashwords') public hashwords: any) { const testHash = '90750f585b9ef687ed3eb54e911a4dd10153fc3dee51fc5548529adfdc3141fe'; const humanHash = hashwords.hashStr(testHash); console.log('Human readbale hash :', humanHash); } }
С помощью декоратора @Inject({ token: any }) мы можем вручную включать зарегистрированные зависимости. Если @Inject() отсутствует, Injector будет использовать аннотацию типа параметра. Это собственно происходит в приложении, когда мы используем constructor(apiService: ApiService).
Улучшаем код с помощью InjectionToken
С предыдущим примером вполне можно работать. Но нам не хватает восхитительной функции Angular + TypeScript приложений — проверки согласованности типов! Конечно, не каждая нужная вам библиотека имеет встроенное определение типа. Но с помощью механизма InjectionToken мы можем определить некоторые базовые интерфейсы для сторонней библиотеки и обеспечить приложение информацией о свойствах и методах, которые собираемся использовать.
#1 Создаём новый файл, который будет содержать конфигурации для сторонних провайдеров
import { InjectionToken, ValueProvider } from '@angular/core'; interface IHashwords { hash: (hash: string) => string[]; hashStr: (hash: string) => string; random: () => string[]; randomStr: () => string; } const Hashwords: InjectionToken<IHashwords> = new InjectionToken<IHashwords>('hashwords'); const HashwordsProvider: ValueProvider = { provide: Hashwords, useValue: window['hashwords']() }; export { IHashwords, Hashwords, HashwordsProvider };
LOC 3–8: Описываем интерфейс для библиотеки с методами и свойствами, которые мы будем использовать в приложении;
LOC 10: Создаём пользовательский InjectionToken с типом интерфейса, который мы только что создали;
LOC 11: Создаём объект ValueProvider, чтобы зарегистрировать его в NgModule
#2 Регистрируем новый провайдер значения
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HashwordsProvider } from './libs.providers' @NgModule({ declarations: [AppComponent], imports: [BrowserModule], providers: [ HashwordsProvider ], bootstrap: [AppComponent] }) export class AppModule { }
#3 Включаем зависимость с определённым типом интерфейса в компонент
LOC 3: Импортируем нужные зависимости из libs.providers.ts;
LOC 12: Теперь можно добавить Hashword InjectionToken, и определить тип для hashwords переменной, которая будет интерфейсом — IHashwords;
LOC 15,16: После этого действия мы можем использовать методы hashwords с автодополнением ввода!
Заключение
Благодаря гибкому механизму регистрирования провайдеров в приложении Angular, мы можем с лёгкостью обернуть сторонние библиотеки и использовать их в приложении так, как если бы они были библиотеками Angular. С помощью механизма Injection Token мы в состоянии даже определить пользовательские типы!
Автор: Mykhailo Churilov
Источник: https://hackernoon.com/
Редакция: Команда webformyself.