web-dev-qa-db-fra.com

Obtenir une référence à une directive utilisée dans un composant

J'ai un composant dont le modèle ressemble à quelque chose comme ceci:

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

J'ai besoin d'accéder à l'instance de classe MyCustomDirective utilisée ici. Lorsque je souhaite accéder à un composant enfant, j'utilise une requête ViewChild.

Existe-t-il une fonctionnalité équivalente pour accéder à une directive enfant?

56
Ben Dilts

Vous pouvez utiliser la propriété exportAs de l'annotation @Directive. Il exporte la directive à utiliser dans la vue parent. À partir de la vue parent, vous pouvez la lier à une variable de vue et y accéder à partir de la classe parent à l'aide de @ViewChild().

Exemple avec un 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');
  }
}

Mettre à jour

Comme mentionné dans les commentaires, il existe une autre alternative à l'approche ci-dessus.

Au lieu d'utiliser exportAs, on pourrait directement utiliser @ViewChild(MyCustomDirective) ou @ViewChildren(MyCustomDirective)

Voici un code pour démontrer la différence entre les trois approches:

@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

}

Mettre à jour

n autre plunker avec plus de précisions

91
Abdulrahman

Il semble que depuis la réponse de @ Abdulrahman, les directives ne sont plus accessibles depuis @ViewChild ou @ViewChildren car ces éléments ne transmettent que les éléments de l’élément DOM lui-même.

Au lieu de cela, vous devez accéder aux directives en utilisant @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
}

Il n’existe plus non plus de propriété directives sur @Component attribut.

16
Toby J