Как Angular управляет неангулярными экземплярами - PullRequest
1 голос
/ 07 июля 2019

У меня есть вопрос о том, как Angular управляет внедрением неангулярных «вещей», когда мы пытаемся внедрить их в компонент.

В частности, давайте рассмотрим пример и используем библиотеку ngx-modialog (https://github.com/shlomiassaf/ngx-modialog) для Angular (я использую версию 6)

Это все просто, если я буду следовать руководству по Quikcstart библиотеки. Однако обратите внимание на эту часть:

constructor(public modal: Modal) { } 
  • Итак, мой вопрос: как экземпляр Modal внедряется в наш конструктор AppComponent?

    Или, более общий вопрос: как Angular "предоставляет" экземпляры этих не обслуживающих классов / функций?

  • Мой второй вопрос: будут ли эти инъекции типа «прототип» (новый экземпляр для новых компонентов, которые мы пытаемся внедрить?)

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 07 июля 2019

У меня есть вопрос о том, как Angular управляет инжекцией неангулярных «вещей», когда мы пытаемся внедрить их в компонент.

Все, что инъецируется упоминается как провайдер в Angular.Каждый поставщик представлен в виде пары информации.

  • что идентифицирует поставщика
  • какое значение имеет поставщик

Angular должен сначала определить провайдера, а затем ему нужно дать значение . идентификатор - это значение JavaScript, которое удовлетворяет выражению ===, а значение - это любой тип JavaScript (т. Е. Объект, массив, строка, число, функция).

Мы можем использовать функцию конструктора класса в качестве идентификатора , поскольку она удовлетворяет выражению ===.

Например;

class MyService {}
// assume MyService is provided via a NgModule somewhere
const x: Type<MyService> = MyService;
console.log(x === MyService); // prints true
console.log(injector.get(x)); // prints MyService instance
console.log(injector.get(MyService)); // prints same MyService instance as above

Когда мы предоставить конструктор класса в качестве идентификатора для провайдера, который называется service .Использование классов с внедрением зависимостей является наиболее распространенной практикой, и мы называем их сервисами, потому что это легче понять.

Итак, мой вопрос, как экземпляр Modal внедряется в наш конструктор AppComponent?

Это работает только потому, что вы добавили декоратор @Component({...}) в начало класса.

TypeScript вызовет декоратор класса при первом объявлении прототипа класса.Декоратор - это функция JavaScript, которая получает прототип в качестве аргумента.На этом этапе Angular проверяет прототип, имеющий функцию конструктора.Используя ссылку на функцию конструктора, Angular может увидеть, сколько существует аргументов и их типы.

Помните выше, где я показал, как конструктор класса может использоваться для извлечения экземпляра из инжектора.Декоратор @Component() делает то же самое с функцией конструктора для извлечения экземпляра модального 1059 *.Он изменяет исходную функцию конструктора, выбирает вводимые значения и передает значения в качестве аргументов.Все это возможно, потому что у нас есть специальные функции в TypeScript, включенные по умолчанию при создании проекта Angular.

Или, более общий вопрос, как Angular "обеспечивает" экземпляры этих не-сервисные классы / функции?

Существуют различные типы провайдеров в Angular.Некоторые из них являются статическими значениями, некоторые являются фабричными функциями и существуют поставщики классов.Если тип Modal является поставщиком класса, то Angular создаст новый экземпляр в первый раз , в который он введен.Затем значение кэшируется и затем повторно используется этим экземпляром инжектор .

Мой второй вопрос, будут ли эти инъекции типа «прототип» (новый экземпляр для новых компонентов, которыемы пытаемся ввести?)

Angular создает дерево инжекторов.Когда поставщик выбран, инжекторы ищут в дереве , пока не будет найден инжектор для этого поставщика .В зависимости от типа провайдера (см. Выше) читается значение .Если это тип класса, тогда этот экземпляр создается и кэшируется новым экземпляром.

Если нет инжекторов, предоставляющих этот тип, возникает ошибка внедрения, когда тип неизвестен.

Откуда взялся Modal?

Modal - это класс abstract , но у них все еще есть уникальная функция конструктора , которую можно использовать как идентификатор для провайдера.

В используемой вами библиотеке есть плагины, которые предоставляют функциональные возможности для класса Modal.Например;плагин начальной загрузки имеет модуль, который объявляет провайдера для класса Modal.Вы можете видеть в исходном коде, что они заменили класс по умолчанию на другой класс с помощью специального провайдера классов.

https://github.com/shlomiassaf/ngx-modialog/blob/44f16f73a5418ac3c41f4ebbc3ed58538a1adea5/projects/plugins/bootstrap/src/lib/bootstrap.module.ts#L17

...