@Self
和
@Host
之间的区别.
角度API文档提供了一些想法.但我不清楚.
为Self提供的示例使用ReflectiveInjector来举例说明用法.
但是,如果有的话,很少会在实际的应用程序代码中使用ReflectiveInjector(可能更多的是在测试中).你能举例说明在这样的测试场景之外你会在哪里使用@Self而不是@Host吗?
看起来当使用@Self时,Angular将仅查找在该指令/组件所在的元素的组件注入器上绑定的值.
看起来当使用@Host时,Angular将查找绑定在该指令/组件所在元素的组件注入器上或父组件的注入器上的值. Angular将此父组件称为“主机”.
更多解释
虽然主要描述不是很有用,但看起来@Self和@Host文档中的示例在澄清如何使用它们以及它们之间的区别(下面复制)方面做得不错.
当试图理解这一点时,可能有助于记住,当Angular依赖注入试图解析构造函数的特定值时,它首先在注入器中查找当前组件,然后通过父注入器向上迭代.这是因为Angular使用分层注入器并允许从祖先注入器继承.
因此,当@Host文档说它“指定一个注入器应该从任何注入器检索依赖关系直到到达当前组件的主机元素”时,这意味着它一旦到达绑定到父节点的注入器就会提前停止这个向上迭代零件.
@Self例子(source)
class Dependency {} @Injectable() class NeedsDependency { constructor(@Self() public dependency: Dependency) {} } let inj = ReflectiveInjector.resolveAndCreate([Dependency,NeedsDependency]); const nd = inj.get(NeedsDependency); expect(nd.dependency instanceof Dependency).toBe(true); inj = ReflectiveInjector.resolveAndCreate([Dependency]); const child = inj.resolveAndCreateChild([NeedsDependency]); expect(() => child.get(NeedsDependency)).toThrowError();
@Host示例(source)
class OtherService {} class HostService {} @Directive({selector: 'child-directive'}) class ChildDirective { logs: string[] = []; constructor(@Optional() @Host() os: OtherService,@Optional() @Host() hs: HostService) { // os is null: true this.logs.push(`os is null: ${os === null}`); // hs is an instance of HostService: true this.logs.push(`hs is an instance of HostService: ${hs instanceof HostService}`); } } @Component({ selector: 'parent-cmp',viewProviders: [HostService],template: '<child-directive></child-directive>',}) class ParentCmp { } @Component({ selector: 'app',viewProviders: [OtherService],template: '<parent-cmp></parent-cmp>',}) class App { }
使用@Self时的示例很重要
假设您有一个用于修改许多类型组件行为的指令;也许这个指令提供了某种配置支持.
该指令绑定到整个应用程序中的许多组件,该指令将其提供程序列表中的某些服务绑定.想要使用此指令动态配置自身的组件将注入它提供的服务.
但是,我们希望确保组件仅使用自己的配置,并且不会意外地注入针对某些父组件的配置服务.因此,我们使用@Self装饰器告诉Angular的依赖注入只考虑该组件元素上提供的配置服务.