Ang*_*hef 26 angular-directive angular
说我有以下标记:
<my-comp myDirective></my-comp>
Run Code Online (Sandbox Code Playgroud)
有没有办法可以从指令访问组件实例?
更具体地说,我希望能够访问MyComponentfrom 的属性和方法MyDirective,理想情况下不向上面的HTML添加任何内容.
Gün*_*uer 29
你可以注射它
class MyDirective {
constructor(private host:MyComponent) {}
Run Code Online (Sandbox Code Playgroud)
严重的限制是,您需要事先知道组件的类型.
另请参阅https://github.com/angular/angular/issues/8277
它还提供了一些解决方法,以便您提前知道类型.
Mic*_*dey 18
如果您想在自定义组件上使用属性指令,您可以让这些组件从抽象类扩展,并将抽象类类型“forwardRef”扩展到您的组件类型。通过这种方式,您可以在抽象类(在您的指令内)上选择 angular 的 DI。
抽象类:
export abstract class MyReference {
// can be empty if you only want to use it as a reference for DI
}
Run Code Online (Sandbox Code Playgroud)
自定义组件:
@Component({
// ...
providers: [
{provide: MyReference, useExisting: forwardRef(() => MyCustomComponent)}
],
})
export class MyCustomComponent extends MyReference implements OnInit {
// ...
}
Run Code Online (Sandbox Code Playgroud)
指示:
@Directive({
selector: '[appMyDirective]'
})
export class CustomDirective{
constructor(private host:MyReference) {
console.log(this.host);
// no accessing private properties of viewContainerRef to see here... :-)
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在扩展抽象类的任何组件上使用该指令。
这当然只适用于您自己的组件。
Sun*_*arg 11
您的指令可能是通用指令,可以应用于您的任何组件。因此,在那种情况下,将无法在构造函数中注入组件,因此这是另一种方法
注入ViewContainerRef in构造函数
constructor(private _viewContainerRef: ViewContainerRef) { }
Run Code Online (Sandbox Code Playgroud)
然后使用
let hostComponent = this._viewContainerRef["_data"].componentView.component;
Run Code Online (Sandbox Code Playgroud)
这取自github问题,就像一个魅力.缺点是需要事先知道组件,但在您的情况下,您需要知道您正在使用的方法.
import { Host, Self, Optional } from '@angular/core';
constructor(
@Host() @Self() @Optional() public hostCheckboxComponent : MdlCheckboxComponent
,@Host() @Self() @Optional() public hostSliderComponent : MdlSliderComponent){
if(this.hostCheckboxComponent) {
console.log("host is a checkbox");
} else if(this.hostSliderComponent) {
console.log("host is a slider");
}
}
Run Code Online (Sandbox Code Playgroud)
图片来源:https: //github.com/angular/angular/issues/8277#issuecomment-323678013
使指令通用的一个可能的解决方法是将组件的模板引用作为 @Input 传递给指令。这增加了一些额外的 html,但它比我尝试过的许多其他技巧效果更好。
@Directive({selector: '[myDirective]'})
export class MyDirective implements OnInit {
@Input() componentRef: any;
@Input() propName: string;
ngOnInit(){
if (this.componentRef != null) {
// Access component properties
this.componentRef[this.propName];
}
}
}
Run Code Online (Sandbox Code Playgroud)
视图中的用法:
@Directive({selector: '[myDirective]'})
export class MyDirective implements OnInit {
@Input() componentRef: any;
@Input() propName: string;
ngOnInit(){
if (this.componentRef != null) {
// Access component properties
this.componentRef[this.propName];
}
}
}
Run Code Online (Sandbox Code Playgroud)
也适用于其他指令。使用装饰器的exportAs属性@Directive来获取指令实例的引用。
<!-- Pass component ref and the property name from component as inputs -->
<app-component #appComponentRef myDirective [componentRef]="appComponentRef" [propName]="'somePropInComponent'" .... >
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14187 次 |
| 最近记录: |