webentwicklung-frage-antwort-db.com.de

Angular 5 Component-Eingangsfunktion, die Parameter übernimmt

Wie übergebe ich in einer Angular 2+ -Komponente eine Callback-Funktion, die Parameter übernimmt?

<app-example [onComplete]="doThing('someParam')"></app-example>

Und manchmal brauche ich keine Parameter wie diese:

<app-example [onComplete]="doSomeThingElse()"></app-example>

Und dann in der Komponente, die ich habe

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
}

Was jedoch am Ende passiert, ist, dass die doThing('someParam') oder doSomeThingElse() sofort ohne Interaktion aufgerufen wird.

Wie soll ich Callback-Funktionen an eine Komponente übergeben, die später aufgerufen werden soll?


BEARBEITEN:

Das eigentliche Problem, das ich hier zu lösen versuche, ist, dass Sie alle übergebenen Funktionen zu einem späteren Zeitpunkt ausführen können. Dies ist für eine Bestätigungskomponente, in der der Benutzer gefragt wird "Sind Sie sicher, dass Sie fortfahren möchten?" Wenn dann die Schaltfläche "Ja, ich bin sicher" gedrückt wird, wird die übergebene Funktion ausgeführt.

6
Chris Barr

Hier ist ein Beispiel für die @Output-Syntax, die @toskv gesucht hat: Angular übergibt die Callback-Funktion als @Input.

Also für dein Beispiel 

<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);
  }
}

Fühlt sich nicht so gut wie [onComplete]="doThing.bind(this, 'someParam')".

14
eric99

Vorlage:

<app-example [someParams]="someParamsObject"
             (complete)="onComplete($event)" >
</app-example>

Komponente:

@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
}

In Ihrer aufrufenden übergeordneten Komponente benötigen Sie eine Funktion mit dem Namen onComplete, die in diesem Fall Parameter des Typs any erhält (die aus @Output stammt, die als EventEmitter<any> definiert ist). Bei Bedarf können Sie auch Ereignisparameter eines beliebigen Typs verwenden, der EventEmitter<YourParticularType> gefällt.

2
dee zg

Sie können eine private Methode in Ihrer Komponente haben:

private doThingFactory(param) {
  return () => this.doThing(param);
}

und benutze es dann so:

<app-example [onComplete]="doThingFactory('someParam')"></app-example>
1
Sagi

Diese Lösung funktioniert nur, wenn Sie über eine Methode verfügen, die aufgerufen werden muss, ohne die Komponente selbst zu aktivieren. In meinem Fall muss ich jedoch eine beobachtbare Methode in der App-Beispielkomponente ausführen und warten, bis die Antwort eine Aktion innerhalb dieser Komponente ausführt.

Wenn jemand das gleiche Problem hat. Hier ist die Lösung dafür.

  1. erstellen Sie eine Schnittstelle.

    export interface Delegate<T> {
      (...args: any[]): T;
    }
    
  2. Erstellen Sie in Ihrer Winkelkomponente eine @Input-Variable

    @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