我有一个问题,当我们尝试将非Angular“事物”注入组件时,它如何管理非Angular“事物”的注入。
特别是,让我们举个例子,将ngx-modialog库(https://github.com/shlomiassaf/ngx-modialog)用于Angular(我正在使用版本6)
如果我遵循该库的Quikcstart指南,这将非常简单。但是,请注意以下部分:
constructor(public modal: Modal) { }
所以,我的问题是Modal
实例如何注入到我们的AppComponent构造函数中?
或更笼统的问题是,Angular如何“提供”这些非服务类/函数的实例?
我的第二个问题是,这些注入类型是否是“ prototype”(我们尝试注入的新组件的新实例?)
感谢您的帮助。
答案 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 类替换为默认类。