J'essaie de créer un composant avec des boutons d'annulation et d'envoi pour éviter le c & p sur chaque formulaire mais je ne trouve pas un moyen de passer des fonctions en paramètre au sélecteur de composant
HTML:
<btn-submit [cancelFunction]='test' [acceptFunction]='test'></btn-submit>
Parent TS:
test = () => console.log("this is a test");
Enfant TS:
import { Component, Input } from '@angular/core';
@Component({
selector: 'btn-submit',
styleUrls: ['./btn.component.scss'],
template: `
<button class="btn" click="cancelFunction()">
<fa name="times"></fa>
</button>
<button class="btn" click="acceptFunction()">
<fa name="check"></fa>
</button>
`
})
export class BtnSubmitComponent {
@Input() cancelFunction: any;
@Input() acceptFunction: any;
}
Si vous souhaitez réellement passer une fonction d'un composant parent à un composant enfant, vous pouvez le faire comme indiqué dans le code ci-dessous.
Mais en utilisant le plus courant @Output
et EventEmitter
, comme indiqué dans d'autres réponses, peut être une meilleure option. La technique @Output ne vous permet pas de transmettre une fonction, mais permet à votre composant parent de recevoir des événements du composant enfant auxquels vous pouvez répondre en appelant une fonction dans le composant parent.
Voici du code qui vous permet de passer une fonction d'un composant parent à un composant enfant.
Composant parent
test = () => console.log("this is a test");
Modèle parent
<pm-star [rating]='product.starRating'
[testFunction]='test'
(ratingClicked)='onRatingClicked($event)'>
</pm-star>
Remarquez les crochets (liaison de propriété) et il ne s'agit pas d'une fonction - appel mais plutôt d'une propriété du composant contenant la fonction.
Composant enfant
@Input() testFunction: any;
Modèle enfant
<div class="crop"
[style.width.px]="starWidth"
[title]="rating"
(click)="testFunction()">
J'ai un stackblitz avec un exemple de travail simple ici: https://stackblitz.com/edit/angular-jwguwk?file=src%2Fapp%2Fapp.component.ts
Vous pouvez utiliser le décorateur @ Output conjointement avec la classe EventEmitter pour y parvenir.
Composant enfant (TypeScript et balisage)
import { Component, Input } from '@angular/core';
@Component({
selector: 'btn-submit',
styleUrls: ['./btn.component.scss'],
template: `
<button class="btn" click="cancelFunction()">
<fa name="times"></fa>
</button>
<button class="btn" click="acceptFunction()">
<fa name="check"></fa>
</button>
`
})
export class BtnSubmitComponent {
@Output() clicked: EventEmitter<any> = new EventEmitter();
cancelFunction(){
this.clicked.emit("CANCELLED"); // Pass any payload as argument
}
acceptFunction{
this.clicked.emit("ACCEPTED"); // Pass any payload as argument
}
}
Balisage parent
<btn-submit (clicked)="onAddClicked($event)" [acceptFunction]='test'></btn-submit>
Fonction TypeScript parent
onAddClicked(event: any){
console.log(event); // Your payload is in 'event'
}
Changez-le de @Input
En @Output
@Output() acceptFunction = new EventEmitter<any>();
Ensuite, à l'intérieur de votre composant lorsque vous souhaitez l'invoquer, faites:
this.acceptFunction.emit();
Le HTML peut rester tel quel.
<btn-submit (cancelFunction)="myCancelFunction()"
(sendFunction)="mySendFunction()></btn-submit>
Chaque fois que vous appelez .emit()
, il déclenchera un événement. Le parent entendra cet événement et appellera la fonction que vous avez liée (par exemple mySendFunction
)