Dans un composant Angular 2+, comment passer d'une fonction de rappel prenant des paramètres? Mon hypothèse de départ était quelque chose comme:
<app-example [onComplete]="doThing('someParam')"></app-example>
Et parfois, je n'ai besoin d'aucun paramètre, comme ceci:
<app-example [onComplete]="doSomeThingElse()"></app-example>
Et puis dans le composant que j'ai
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
@Input() public onComplete: () => void;
//run `this.onComplete()` somewhere as needed
}
Mais ce qui finit par se produire, c'est que la fonction doThing('someParam')
ou doSomeThingElse()
est immédiatement appelée sans aucune interaction.
Comment suis-je censé transmettre des fonctions de rappel à un composant pour l'appeler ultérieurement?
Le problème que j'essaie de résoudre ici est de pouvoir exécuter ultérieurement toute fonction transmise. Ceci est pour un composant de confirmation qui demandera à l'utilisateur "êtes-vous sûr de vouloir continuer?" et s’ils appuient sur le bouton "Oui, je suis sûr", la fonction transmise s’exécutera.
Voici un exemple de syntaxe @Output
que recherchait @toskv, Fonction de rappel de passage angulaire au composant enfant sous la forme @Input
Donc, pour votre exemple,
<app-example
(onComplete)="doThing()"
[completedParam]="'someParam'"></app-example>
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
@Output() public onComplete: EventEmitter<any> = new EventEmitter();
@Input() completedParam;
runOnComplete(): void {
this.onComplete.emit(this.completedParam);
}
}
Ne se sent pas aussi bon que [onComplete]="doThing.bind(this, 'someParam')"
.
Modèle:
<app-example [someParams]="someParamsObject"
(complete)="onComplete($event)" >
</app-example>
Composant:
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
@Input()
someParams: YourParamsType;
@Output()
complete:EventEmitter<any> = new EventEmitter<any>();
//run `this.complete(this.someParams)` somewhere as needed and
//pack in some params if you need
}
Dans votre composant parent appelant, vous avez besoin d'une fonction nommée onComplete
qui reçoit le paramètre de type any
dans ce cas (qui provient de @Output
défini par EventEmitter<any>
). Si vous avez besoin, vous pouvez également avoir des paramètres d'événement d'un type particulier que vous aimez, EventEmitter<YourParticularType>
.
Vous pouvez avoir une méthode privée dans votre composant:
private doThingFactory(param) {
return () => this.doThing(param);
}
et ensuite l'utiliser comme ça:
<app-example [onComplete]="doThingFactory('someParam')"></app-example>
Ladite solution ne fonctionnera que si vous avez une méthode qui doit être appelée sans effectuer d’action sur le composant lui-même. Cependant, dans mon cas, je dois exécuter une méthode observable à l'intérieur du composant exemple d'application et attendre que la réponse effectue une action à l'intérieur de ce composant.
Si quelqu'un a le même problème. Voici la solution pour cela.
créer une interface.
export interface Delegate<T> {
(...args: any[]): T;
}
Sur votre composant angulaire, créez une variable @Input
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class AppExampleComponent {
@Input() executeWhen: Delegate<Observable<any>>;
runOnComplete(): void {
this.executeWhen().subscribe(() => // do some action);
}
}