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