次のマークアップがあるとします。
<my-comp myDirective></my-comp>
コンポーネントインスタンスにアクセスする方法はありますかディレクティブから?
より具体的には、MyComponent
からMyDirective
のプロパティとメソッドにアクセスできるようにしたい、理想的には上記のHTMLに何も追加せずにです。
注入するだけです
class MyDirective {
constructor(private Host:MyComponent) {}
重大な制限は、コンポーネントのタイプを事前に知る必要があることです。
こちらもご覧ください https://github.com/angular/angular/issues/8277
タイプを事前に知らない場合の回避策も提供します。
ディレクティブは、任意のコンポーネントに適用できる汎用的なものにすることができます。したがって、その場合、コンストラクタにコンポーネントを注入することはできません。したがって、同じことを行う別の方法があります
コンストラクターにViewContainerRef
を挿入します
constructor(private _viewContainerRef: ViewContainerRef) { }
そして、それを使用して取得します
let hostComponent = this._viewContainerRef["_data"].componentView.component;
これは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");
}
}
クレジット: https://github.com/angular/angular/issues/8277#issuecomment-32367801
カスタムコンポーネントで属性ディレクティブを使用する場合、これらのコンポーネントを抽象クラスから拡張し、抽象クラスタイプをコンポーネントタイプに「forwardRef」することができます。このようにして、(ディレクティブ内の)抽象クラスで角度のDIを選択できます。
抽象クラス:
export abstract class MyReference {
// can be empty if you only want to use it as a reference for DI
}
カスタムコンポーネント:
@Component({
// ...
providers: [
{provide: MyReference, useExisting: forwardRef(() => MyCustomComponent)}
],
})
export class MyCustomComponent extends MyReference implements OnInit {
// ...
}
指令:
@Directive({
selector: '[appMyDirective]'
})
export class CustomDirective{
constructor(private Host:MyReference) {
console.log(this.Host);
// no accessing private properties of viewContainerRef to see here... :-)
}
}
このようにして、抽象クラスを拡張するコンポーネントでディレクティブを使用できます。
もちろん、これは独自のコンポーネントでのみ機能します。