Angular Injector vs ViewContainerRef.Injector vs ViewContainerRef.parentInjector

Angular Injector vs ViewContainerRef.Injector vs ViewContainerRef.parentInjector,angular,typescript,dependency-injection,Angular,Typescript,Dependency Injection,假设我们有以下情况: @Directive({ selector: "[appSome]" }) export class SomeDirective { public constructor( private viewContainerRef: ViewContainerRef, private injector: Injector, ) { console.log(`injector === viewContainerRef.inj

假设我们有以下情况:

@Directive({ selector: "[appSome]" })
export class SomeDirective {
    public constructor(
        private viewContainerRef: ViewContainerRef,
        private injector: Injector,
    ) {
      console.log(`injector === viewContainerRef.injector: ${injector === viewContainerRef.injector}`);
      console.log(`injector === viewContainerRef.parentInjector: ${injector === viewContainerRef.parentInjector}`);
      console.log(`viewContainerRef.injector === viewContainerRef.parentInjector: ${viewContainerRef.injector === viewContainerRef.parentInjector}`);
    }
}
这3个喷油器之间有什么区别

  • this.injector
  • this.viewContainerRef.injector
  • this.viewContainerRef.parentInjector

  • 在上面的测试中,它们都是不同的实例。

    首先,您在构造函数中得到的注入器是所谓的

    这是它的:

    Angular仅获取视图数据和节点定义,并可在需要时通过函数实例化喷油器实例:

    export function createInjector(view: ViewData, elDef: NodeDef): Injector {
      return new Injector_(view, elDef);
    }
    
    现在让我们回到您的指令:

                                     SomeDirective 
                                         |
                                        deps
                                   /            \
                            Injector         ViewContainer
    
    要创建指令实例,请通过专用函数解析依赖项

    假设您有一个组件,如:

    @Component({
      selector: 'my-app',
      template: '<h2 appSome>Hello</h2>'
    })
    export class AppComponent {} 
    
    ViewContainerRef
    实例是在视图节点创建的早期创建的。由于需要通过DI角度标记
    h2
    节点使用特殊标志,因此它可以在h2节点数据中实例化
    ViewContainerRef
    和该实例

    if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
       nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
    }
    
    其中:

    所以我们这里有:
    Injector
    ViewContainer
    ,它们指向相同的视图和相同的elDef

    现在让我们看看ViewContainerRef:

    案例1 因为viewContainerRef.injector getter使用相同的视图和elDef创建injector的新实例

    因此,以下是正确的:

    injector.view === viewContainerRef.injector.view
    injector.elDef === viewContainerRef.injector.elDef
    
    案例2 因为parentInjector getter将使用父视图和父elDef获取Injector的新实例

    这里的父视图是主机视图,elDef是我的应用程序

    案例3 显然,它们并不相等,因为它们指向不同的视图和elDef,并且是通过
    new
    操作符创建的


    最后,您可以阅读:


    首先,您在构造函数中得到的注入器是所谓的

    这是它的:

    Angular仅获取视图数据和节点定义,并可在需要时通过函数实例化喷油器实例:

    export function createInjector(view: ViewData, elDef: NodeDef): Injector {
      return new Injector_(view, elDef);
    }
    
    现在让我们回到您的指令:

                                     SomeDirective 
                                         |
                                        deps
                                   /            \
                            Injector         ViewContainer
    
    要创建指令实例,请通过专用函数解析依赖项

    假设您有一个组件,如:

    @Component({
      selector: 'my-app',
      template: '<h2 appSome>Hello</h2>'
    })
    export class AppComponent {} 
    
    ViewContainerRef
    实例是在视图节点创建的早期创建的。由于需要通过DI角度标记
    h2
    节点使用特殊标志,因此它可以在h2节点数据中实例化
    ViewContainerRef
    和该实例

    if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
       nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
    }
    
    其中:

    所以我们这里有:
    Injector
    ViewContainer
    ,它们指向相同的视图和相同的elDef

    现在让我们看看ViewContainerRef:

    案例1 因为viewContainerRef.injector getter使用相同的视图和elDef创建injector的新实例

    因此,以下是正确的:

    injector.view === viewContainerRef.injector.view
    injector.elDef === viewContainerRef.injector.elDef
    
    案例2 因为parentInjector getter将使用父视图和父elDef获取Injector的新实例

    这里的父视图是主机视图,elDef是我的应用程序

    案例3 显然,它们并不相等,因为它们指向不同的视图和elDef,并且是通过
    new
    操作符创建的


    最后,您可以阅读:

    injector.view === viewContainerRef.injector.view
    injector.elDef === viewContainerRef.injector.elDef
    
    injector === viewContainerRef.parentInjector => fail
    
    viewContainerRef.injector === viewContainerRef.parentInjector  => fail