当 token 可以是多个值时,通过 Injector.get() 获取父 Component
Getting parent Component via Injector.get() when token can be multiple values
我想做什么:
- 使用单个指令的多个不同组件
- 调用指令时,我需要能够获取调用指令的 parent/host 组件。
Plnkr -> http://plnkr.co/edit/Do4qYfDLtarRQQEBphW3?p=preview
在查看angular.io文档时,我发现"Injector"可以用来在构造函数中获取父组件
constructor(private el: ElementRef, private hostComponent:Injector){
el.nativeElement.draggable = 'true';
}
这样做,我得到了注入器对象。据我所知,我应该使用
this.hostComponent.get(INJECTORTOKEN)
我难以理解的问题是,Angular 中提供的示例假设您知道要在令牌中提供的组件类型。即:
this.hostComponent.get(Image);
this.hostComponent.get(Box);
在 pnkr 示例中,我的模板中有两个组件
<div>
<h2>Hello {{name}}</h2>
<my-image></my-image> <!-- Uses the "My Directive" -->
<my-box></my-box> <!-- Uses the "My Directive" -->
</div>
我的问题是,在"mydirective.ts"。当我不知道父级是 "my-image" 还是 'my-box' 组件时,如何利用 "injector.get()"。
在提供的示例中,指令被触发 "ondrag()"。查看控制台,获取日志消息。
非常感谢任何帮助。
谢谢你。
我知道几种方法:
1) 通过 class-interface
找到一个 parent
您需要提供商的 class-interface 令牌,例如:
export abstract class Parent { }
之后你应该在 Box
和 Image
组件上写一个别名提供者
box.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Box) }]
image.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Image) }]
然后在您的指令中使用它,如下所示
myDirective.ts
export class MyDirective {
constructor(@Optional() private parent: Parent){}
@HostListener('dragstart',['$event']) ondragstart(event){
switch(this.parent.constructor) {
case Box:
console.log('This is Box');
break;
case Image:
console.log('This is Image');
break;
}
}
}
这里是Plunker
2) 将你所有的 parent 作为 Optional
令牌注入
myDirective.ts
export class MyDirective {
constructor(
@Optional() private image: Image,
@Optional() private box: Box){}
@HostListener('dragstart',['$event']) ondragstart(event){
if(this.box) {
console.log('This is Box');
}
if(this.image) {
console.log('This is Image');
}
}
}
Plunker 对于这种情况
3) 使用 Injector
喜欢
export class MyDirective {
constructor(private injector: Injector){}
@HostListener('dragstart',['$event']) ondragstart(event){
const boxComp = this.injector.get(Box, 0);
const imageComp = this.injector.get(Image, 0);
if(boxComp) {
console.log('This is Box');
}
if(imageComp) {
console.log('This is Image');
}
}
}
我想做什么:
- 使用单个指令的多个不同组件
- 调用指令时,我需要能够获取调用指令的 parent/host 组件。
Plnkr -> http://plnkr.co/edit/Do4qYfDLtarRQQEBphW3?p=preview
在查看angular.io文档时,我发现"Injector"可以用来在构造函数中获取父组件
constructor(private el: ElementRef, private hostComponent:Injector){
el.nativeElement.draggable = 'true';
}
这样做,我得到了注入器对象。据我所知,我应该使用
this.hostComponent.get(INJECTORTOKEN)
我难以理解的问题是,Angular 中提供的示例假设您知道要在令牌中提供的组件类型。即:
this.hostComponent.get(Image);
this.hostComponent.get(Box);
在 pnkr 示例中,我的模板中有两个组件
<div>
<h2>Hello {{name}}</h2>
<my-image></my-image> <!-- Uses the "My Directive" -->
<my-box></my-box> <!-- Uses the "My Directive" -->
</div>
我的问题是,在"mydirective.ts"。当我不知道父级是 "my-image" 还是 'my-box' 组件时,如何利用 "injector.get()"。
在提供的示例中,指令被触发 "ondrag()"。查看控制台,获取日志消息。
非常感谢任何帮助。
谢谢你。
我知道几种方法:
1) 通过 class-interface
找到一个 parent您需要提供商的 class-interface 令牌,例如:
export abstract class Parent { }
之后你应该在 Box
和 Image
组件上写一个别名提供者
box.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Box) }]
image.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Image) }]
然后在您的指令中使用它,如下所示
myDirective.ts
export class MyDirective {
constructor(@Optional() private parent: Parent){}
@HostListener('dragstart',['$event']) ondragstart(event){
switch(this.parent.constructor) {
case Box:
console.log('This is Box');
break;
case Image:
console.log('This is Image');
break;
}
}
}
这里是Plunker
2) 将你所有的 parent 作为 Optional
令牌注入
myDirective.ts
export class MyDirective {
constructor(
@Optional() private image: Image,
@Optional() private box: Box){}
@HostListener('dragstart',['$event']) ondragstart(event){
if(this.box) {
console.log('This is Box');
}
if(this.image) {
console.log('This is Image');
}
}
}
Plunker 对于这种情况
3) 使用 Injector
喜欢
export class MyDirective {
constructor(private injector: Injector){}
@HostListener('dragstart',['$event']) ondragstart(event){
const boxComp = this.injector.get(Box, 0);
const imageComp = this.injector.get(Image, 0);
if(boxComp) {
console.log('This is Box');
}
if(imageComp) {
console.log('This is Image');
}
}
}