首先,
喷油器
你进入构造器是所谓的
Merge Injector
.
这是它
definition
以下内容:
class Injector_ implements Injector {
constructor(private view: ViewData, private elDef: NodeDef|null) {}
...
}
Angular只获取视图数据和节点定义,并可以在需要时通过
createInjector
功能:
export function createInjector(view: ViewData, elDef: NodeDef): Injector {
return new Injector_(view, elDef);
}
现在让我们回到你的指示:
SomeDirective
|
deps
/ \
Injector ViewContainer
创建指令实例,角度通过专用函数解析依赖项
resolveDep
export function resolveDep(view, elDef) {
...
case ViewContainerRefTokenKey:
return asElementData(searchView, elDef.nodeIndex).viewContainer;
...
case InjectorRefTokenKey:
return createInjector(searchView, elDef);
...
}
假设您有一个组件,比如:
@Component({
selector: 'my-app',
template: '<h2 appSome>Hello</h2>'
})
export class AppComponent {}
在这种情况下:
SomeDirective
|
deps
/ \
Injector ViewContainer
|| ||
\/ \/
resolveDep(AppComponent view, h2 elDef) resolveDep(AppComponent view, h2 elDef)
|| ||
\/ \/
createInjector viewContainerRef (AppComponent view, h2 elDef)
(created early)
||
\/
new Injector(AppComponent view, h2 elDef)
ViewContainerRef
实例是在视图节点创建的早期创建的。因为你需要
查看容器引用
通过DI角标记
h2
带有特殊标志的节点,这样它就可以实例化
查看容器引用
和
store
h2节点数据中的此实例。
if (nodeDef.flags & 16777216 ) {
nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
}
在哪里?
createViewContainerData
以下内容:
export function createViewContainerData(
view: ViewData, elDef: NodeDef, elData: ElementData): ViewContainerData {
return new ViewContainerRef_(view, elDef, elData);
}
所以我们这里有:
Injector
和
ViewContainer
这表明了相同的观点和相同的长辈。
现在让我们看看viewContainerRef
definition
以下内容:
class ViewContainerRef_ implements ViewContainerData {
...
constructor(private _view: ViewData, private _elDef: NodeDef, private _data: ElementData) {}
...
get injector(): Injector { return new Injector_(this._view, this._elDef); }
get parentInjector(): Injector {
let view = this._view;
let elDef = this._elDef.parent;
while (!elDef && view) {
elDef = viewParentEl(view);
view = view.parent !;
}
return view ? new Injector_(view, elDef) : new Injector_(this._view, null);
}
...
}
案例1
injector === viewContainerRef.injector => fail
因为
viewContainerRef.Injector getter创建新实例
具有相同视图和接骨板的注入器。
因此,以下是正确的:
injector.view === viewContainerRef.injector.view
injector.elDef === viewContainerRef.injector.elDef
案例2
injector === viewContainerRef.parentInjector => fail
因为parentInjector getter将使用父视图和父eldef获取新的注入器实例。
这里的父视图是主机视图,eldef是我的应用程序。
案例3
viewContainerRef.injector === viewContainerRef.parentInjector => fail
应该很明显,他们不平等,因为指向不同的观点和长辈也是通过
new
操作员。
最后,您可以阅读:
What you always wanted to know about Angular Dependency Injection tree