web-dev-qa-db-fra.com

Fonction d'entrée angulaire à 5 composants qui prend des paramètres

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?


MODIFIER:

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.

6
Chris Barr

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')".

14
eric99

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>.

2
dee zg

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>
1
Sagi

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.

  1. créer une interface.

    export interface Delegate<T> {
      (...args: any[]): T;
    }
    
  2. 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);
      }
    }
    
0
Yhan