web-dev-qa-db-fra.com

Comment passer plusieurs paramètres à @Directives in Angular avec TypeScript?

Depuis que j'ai créé @Directive en tant que SelectableDirective, je suis un peu confus quant à la manière de passer la valeur plusieurs à la directive custom. J'ai beaucoup cherché mais je n'ai pas trouvé de solution adéquate dans Angular avec TypeScript.

Voici ce que mon exemple de code est: 

Composant parent en tant que MCQComponent:

import { Component, OnInit } from '@angular/core';
import { Question } from '../question/question';
import { AppService } from '../app.service/app.service';
import { SelectableDirective } from '../selectable.directive/selectable.directive';
import { ResultComponent } from '../result-component/result.component';

@Component({
    selector: 'mcq-component',
    template: "
         .....
        <div *ngIf = 'isQuestionView'>
            <ul>
                <li *ngFor = 'let opt of currentQuestion.options' 
                    [selectable] = 'opt'
                    (selectedOption) = 'onOptionSelection($event)'>
                    {{opt.option}}
                </li>
            </ul>
            .....
        </div>

    "
    providers: [AppService],
    directives: [SelectableDirective, ResultComponent]
})
export class MCQComponent implements OnInit{
    private currentIndex:any = 0;
    private currentQuestion:Question = new Question();
    private questionList:Array<Question> = [];
    ....
    constructor(private appService: AppService){}
    ....
}

Il s'agit d'un composant parent ayant une directive personnalisée [selectable] qui prend un paramètre appelé opt

Voici le code pour cette directive: 

import { Directive, HostListener, ElementRef, Input, Output, EventEmitter } from '@angular/core'
import { Question } from '../question/question';

@Directive({
    selector: '[selectable]'
})
export class SelectableDirective{
    private el: HTMLElement;
    @Input('selectable') option:any;

    ...
}

Donc, ici, je veux passer le composant plus de paramètres du parent, comment y arriver?

45
Shree

Depuis le Documentation

Comme pour les composants, vous pouvez ajouter autant de liaisons de propriété de directive que vous avez besoin en les enfilant dans le modèle. 

Ajoutez une propriété d'entrée à HighlightDirective appelée defaultColor:

@Input() defaultColor: string;

Markup

<p [myHighlight]="color" defaultColor="Violet">
  Highlight me too!
</p>

Angular sait que la liaison defaultColor appartient à HighlightDirective car vous l'avez rendue publique avec le @Input décorateur.

Dans tous les cas, le décorateur @Input indique à Angular que cette propriété est public et disponible pour la liaison par un composant parent. Sans pour autant @Input, Angular refuse de se lier à la propriété.

Pour votre exemple

Avec beaucoup de paramètres

Ajoutez des propriétés dans la classe Directive avec le décorateur @Input()

@Directive({
    selector: '[selectable]'
})
export class SelectableDirective{
    private el: HTMLElement;

    @Input('selectable') option:any;   
    @Input('first') f;
    @Input('second') s;

    ...
}

Et dans le modèle, passez les propriétés liées à votre élément li

<li *ngFor = 'let opt of currentQuestion.options' 
    [selectable] = 'opt' 
    [first]='YourParameterHere'
    [second]='YourParameterHere'
    (selectedOption) = 'onOptionSelection($event)'>
    {{opt.option}}
</li>

Ici, dans l'élément li, nous avons une directive avec le nom selectable. Dans selectable, nous avons deux @Input() ', f avec name first et s avec name second. Nous avons appliqué ces deux propriétés li avec les noms [first] et [second]. Et notre directive trouvera ces propriétés sur cet élément li, défini pour lui avec @Input() decorator. Ainsi, selectable, [first] et [second] seront liés à chaque directive sur li, qui possède une propriété avec ces noms.

Avec un seul paramètre

@Directive({
    selector: '[selectable]'
})
export class SelectableDirective{
    private el: HTMLElement;

    @Input('selectable') option:any;   
    @Input('params') params;

    ...
}

Markup

<li *ngFor = 'let opt of currentQuestion.options' 
    [selectable] = 'opt' 
    [params]='{firstParam: 1, seconParam: 2, thirdParam: 3}'
    (selectedOption) = 'onOptionSelection($event)'>
    {{opt.option}}
</li>
73
Suren Srapyan

pour passer de nombreuses options, vous pouvez passer un objet à un décorateur @Input avec des données personnalisées sur une seule ligne.

Dans le modèle

<li *ngFor = 'let opt of currentQuestion.options' 
                [selectable] = 'opt'
                [myOptions] ="{first: opt.val1, second: opt.val2}" // these are your multiple parameters
                (selectedOption) = 'onOptionSelection($event)' >
     {{opt.option}}
</li>

donc dans la classe de directive

@Directive({
  selector: '[selectable]'
})

export class SelectableDirective{
  private el: HTMLElement;
  @Input('selectable') option:any;
  @Input('myOptions') data;

  //do something with data.first
  ...
  // do something with data.second
}
9
Dag

Une autre option intéressante consiste à utiliser la variable Directive en tant qu'élément et non en tant qu'attribut.

@Directive({
   selector: 'app-directive'
})
export class InformativeDirective implements AfterViewInit {

    @Input()
    public first: string;

    @Input()
    public second: string;

    ngAfterViewInit(): void {
       console.log(`Values: ${this.first}, ${this.second}`);
    }
}

Et cette directive peut être utilisée comme ça:

<app-someKindOfComponent>
    <app-directive [first]="'first 1'" [second]="'second 1'">A</app-directive>
    <app-directive [first]="'First 2'" [second]="'second 2'">B</app-directive>
    <app-directive [first]="'First 3'" [second]="'second 3'">C</app-directive>
</app-someKindOfComponent>`

Simple, soigné et puissant.

2
Aharon Ohayon

Semblable aux solutions ci-dessus, j’ai utilisé @Input() dans une directive et capable de transmettre plusieurs tableaux de valeurs dans la directive.

selector: '[selectorHere]',

@Input() options: any = {};

Input.html

<input selectorHere [options]="selectorArray" />

Tableau du fichier TS 

selectorArray= {
  align: 'left',
  prefix: '$',
  thousands: ',',
  decimal: '.',
  precision: 2
};
0
Deepak