Angular如何管理非Angular实例

时间:2019-07-07 09:48:38

标签: angular dependency-injection

我有一个问题,当我们尝试将非Angular“事物”注入组件时,它如何管理非Angular“事物”的注入。

特别是,让我们举个例子,将ngx-modialog库(https://github.com/shlomiassaf/ngx-modialog)用于Angular(我正在使用版本6)

如果我遵循该库的Quikcstart指南,这将非常简单。但是,请注意以下部分:

constructor(public modal: Modal) { } 
  • 所以,我的问题是Modal实例如何注入到我们的AppComponent构造函数中?

    或更笼统的问题是,Angular如何“提供”这些非服务类/函数的实例?

  • 我的第二个问题是,这些注入类型是否是“ prototype”(我们尝试注入的新组件的新实例?)

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

  

我有一个问题,当我们尝试将非Angular“事物”注入组件时,Angular如何管理注入。

可注入的所有内容在Angular中都称为提供者。每个提供者都作为一个信息呈现。

  • 什么标识了提供商
  • 提供者有什么价值

Angular首先需要标识一个提供者,然后需要提供 identifier 是满足===表达式的JavaScript值,而 value 是任何JavaScript类型(即对象,数组,字符串,数字,函数)。

我们可以使用类构造函数作为 identifier ,因为它满足===表达式。

例如;

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

当我们为提供程序提供一个类构造函数作为 identifier 时,它被称为 service 。将类与依赖关系注入一起使用是最常见的做法,我们将它们称为服务是因为它更易于理解。

  

所以,我的问题是Modal实例如何注入到我们的AppComponent构造函数中?

之所以起作用,是因为您在类的顶部添加了一个@Component({...})装饰器。

当首次声明类原型时,TypeScript将调用类装饰器。装饰器是一个JavaScript函数,它接收原型作为参数。 Angular在此阶段检查具有构造函数的原型。使用对构造函数Angular的引用,可以看到有多少个参数及其类型。

记住上面的内容,我展示了如何使用类构造函数从注入器获取实例。 @Component()装饰器对构造函数执行相同的操作,以获取 modal 的实例。它修改原始的构造函数,获取可注入的值并将这些值作为参数传递。所有这一切都是可能的,因为在创建Angular项目时,默认情况下启用了TypeScript的特殊功能。

  

或更笼统的问题是,Angular如何“提供”这些非服务类/函数的实例?

Angular中有不同类型的 providers 。有些是静态值,有些是工厂函数,还有类提供程序。如果类型Modal是一个类提供程序,则Angular将在第一次注入时创建新实例。然后,该值将被该 injector 实例缓存并重新使用。

  

我的第二个问题是,这些注入类型是否为“ prototype”(我们尝试注入的新组件的新实例?)

Angular创建喷射器的 tree 。提取 provider 后,注射器将搜索 tree ,直到找到该 provider 的注射器。根据提供程序的类型(请参见上文),读取 value 。如果是类类型,则由该注入器创建并缓存一个新实例。

如果没有提供该类型的喷油器,则会引发未知类型的喷油错误。

莫代尔来自哪里?

Modal是一个抽象类,但是它们仍然具有 unique 构造函数,可以用作 identifier 提供者。

您正在使用的库具有可为Modal类提供功能的插件。例如; bootstrap插件具有一个模块,该模块为Modal类声明 provider 。您可以在源代码中看到,他们已经通过使用自定义类提供程序将 different 类替换为默认类。

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