web-dev-qa-db-ja.com

コンポーネントで使用されるディレクティブへの参照を取得します

次のようなテンプレートのコンポーネントがあります。

<div [my-custom-directive]>Some content here</div>

ここで使用されるMyCustomDirectiveクラスインスタンスにアクセスする必要があります。子コンポーネントにアクセスしたいときは、ViewChildクエリを使用します。

子ディレクティブにアクセスするための同等の機能はありますか?

56
Ben Dilts

@DirectiveアノテーションのexportAsプロパティを使用できます。親ビューで使用されるディレクティブをエクスポートします。親ビューから、ビュー変数にバインドし、@ViewChild()を使用して親クラスからアクセスできます。

plunker の例:

@Directive({
  selector:'[my-custom-directive]',
  exportAs:'customdirective'   //the name of the variable to access the directive
})
class MyCustomDirective{
  logSomething(text){
    console.log('from custom directive:', text);
  }
}

@Component({
    selector: 'my-app',
    directives:[MyCustomDirective],
    template: `
    <h1>My First Angular 2 App</h1>

    <div #cdire=customdirective my-custom-directive>Some content here</div>
    `
})
export class AppComponent{
  @ViewChild('cdire') element;

  ngAfterViewInit(){
    this.element.logSomething('text from AppComponent');
  }
}

更新

コメントで述べたように、上記のアプローチに代わる別の方法があります。

exportAsを使用する代わりに、@ViewChild(MyCustomDirective)または@ViewChildren(MyCustomDirective)を直接使用できます

以下に、3つのアプローチの違いを示すコードを示します。

@Component({
    selector: 'my-app',
    directives:[MyCustomDirective],
    template: `
    <h1>My First Angular 2 App</h1>

    <div my-custom-directive>First</div>
    <div #cdire=customdirective my-custom-directive>Second</div>
    <div my-custom-directive>Third</div>
    `
})
export class AppComponent{
  @ViewChild('cdire') secondMyCustomDirective; // Second
  @ViewChildren(MyCustomDirective) allMyCustomDirectives; //['First','Second','Third']
  @ViewChild(MyCustomDirective) firstMyCustomDirective; // First

}

更新

より明確な別のプランカー

91
Abdulrahman

@Abdulrahmanの回答以来、ディレクティブは@ViewChildまたは@ViewChildrenからアクセスできなくなりました。これらはDOM要素自体の項目のみを渡すからです。

代わりに、@ContentChild/@ContentChildrenを使用してディレクティブにアクセスする必要があります。

@Component({
    selector: 'my-app',
    template: `
    <h1>My First Angular 2 App</h1>

    <div my-custom-directive>First</div>
    <div #cdire=customdirective my-custom-directive>Second</div>
    <div my-custom-directive>Third</div>
    `
})
export class AppComponent{
  @ContentChild('cdire') secondMyCustomDirective; // Second
  @ContentChildren(MyCustomDirective) allMyCustomDirectives; //['First','Second','Third']
  @ContentChild(MyCustomDirective) firstMyCustomDirective; // First
}

@Component属性にdirectivesプロパティもなくなりました。

16
Toby J