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?
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éedefaultColor
:@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>
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
}
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.
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
};