web-dev-qa-db-ja.com

ディレクティブからホストコンポーネントにアクセスする方法

次のマークアップがあるとします。

<my-comp myDirective></my-comp>

コンポーネントインスタンスにアクセスする方法はありますかディレクティブから

より具体的には、MyComponentからMyDirectiveのプロパティとメソッドにアクセスできるようにしたい、理想的には上記のHTMLに何も追加せずにです。

22
AngularChef

注入するだけです

class MyDirective {
  constructor(private Host:MyComponent) {}

重大な制限は、コンポーネントのタイプを事前に知る必要があることです。

こちらもご覧ください https://github.com/angular/angular/issues/8277
タイプを事前に知らない場合の回避策も提供します。

23

ディレクティブは、任意のコンポーネントに適用できる汎用的なものにすることができます。したがって、その場合、コンストラクタにコンポーネントを注入することはできません。したがって、同じことを行う別の方法があります

コンストラクターにViewContainerRefを挿入します

constructor(private _viewContainerRef: ViewContainerRef) { }

そして、それを使用して取得します

let hostComponent = this._viewContainerRef["_data"].componentView.component;
11
Sunil Garg

これは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

7
Anthony

カスタムコンポーネントで属性ディレクティブを使用する場合、これらのコンポーネントを抽象クラスから拡張し、抽象クラスタイプをコンポーネントタイプに「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... :-)
  }

}

このようにして、抽象クラスを拡張するコンポーネントでディレクティブを使用できます。

もちろん、これは独自のコンポーネントでのみ機能します。

1
Michiel Windey