Überprüfen Sie, ob eine Ausgabe an der Komponente vorhanden ist


14

Betrachten Sie die folgende Komponente:

@Component({
  selector: 'app-test'
  template: 'Hello!'
}}
export class TestComponent {
  @Output() readonly selectionChange = new EventEmitter<SomeTypeHere>();
}

Mit dem Anruf:

<app-test (selectedChange)="selectedChangeHandler($event)"></app-test>

Beachten Sie, dass ich selectedChangeanstelle des richtigen Ausgabenamens geschrieben habe selectionChange. Winkel 9 mit strictTemplatesaktivierter Flagge hat mir überhaupt nicht geholfen. Es schlug lautlos fehl. Der interessante Teil ist, dass wenn ich das Gleiche für mache @Input, die App die Fehler abfängt und nicht kompiliert.

Gibt es eine Möglichkeit, einen Fehler auszulösen, wenn ich versuche, einen nicht vorhandenen "anzuhören" @Output?


1
Gab es Fehler mit früheren Versionen von Angular? Ich denke, es hat nie einen Fehler gemacht
Aravind

@Aravind nein, es hat nie Fehler geworfen. Ich frage, ob es möglich ist. Danke im Voraus.
dev_054

warum willst du fehler werfen? Gibt es einen besonderen Bedarf? Ich versuche Ihre Frage zu verstehen
Aravind

@Aravind Nun, ich arbeite mit vielen Entwicklern an einer Unternehmens-App, daher ist es wichtig, Informationen / Warnungen / Fehler zu haben. Manchmal ändert / entfernt jemand eine @Output()in einer freigegebenen Bibliothek oder sogar in der App und vergisst, die Anrufe zu entfernen ... und da wir keine Kompilierungsfehler haben, wie wir sie haben @Input(), können wir nicht genau herausfinden, was bestimmte Probleme verursacht (oder sogar, um keinen Müll im Code zu behalten). Unit-Tests könnten hilfreich sein? Vielleicht, aber zur Zeit ist es aufgrund der Zeit noch nicht möglich.
dev_054

Antworten:


3

Es gibt keine geworfen Fehler , weil die Ereignisbindung in Angular verwendet wird , nicht nur mit @Outputs und EventEmitters, sondern auch auf die hören DOM - Ereignisse wie click, keyupusw. Es gibt sogar verwendet werden könnte , um zu hören , benutzerdefinierte Ereignisse . Wenn Sie beispielsweise ein benutzerdefiniertes Ereignis in der untergeordneten Komponente erstellen und ausgeben:

constructor (private el: ElementRef) {}
ngOnInit(): void {
    const domEvent = new CustomEvent('selectedChange', { custom: true });
    this.el.nativeElement.dispatchEvent(domEvent);
}

Dann können Sie es in der übergeordneten Komponente anhand ihres Namens abfangen:

<app-test (selectedChange)="selectedChangeHandler($event)"></app-test>

Angular verwendet target.addEventListener (Typ, Listener [, Optionen]); intern (Sie können sicherstellen, dass Sie sich die folgenden Links ansehen), wo typesich eine beliebige Zeichenfolge befinden könnte.

Deshalb wird keine Ausnahme ausgelöst, wenn keine passenden @Outputs gefunden werden.

listenToElementOutputs

DefaultDomRenderer2.listen

EventManager.addEventListener

DomEventsPlugin.addEventListener


Hey @Kirill Simonov, danke für deine Antwort! Nehmen Sie Ihre Aussage: "Es wird kein Fehler ausgegeben, da die Ereignisbindung in Angular nicht nur mit @Outputs und EventEmitters verwendet wird, sondern auch, um die DOM-Ereignisse wie Klicken, Keyup usw. abzuhören." Warum dann, wenn Sie bestehen? ein inexistent @Input()(denken Sie daran , dass Eingänge die gleichen Merkmale aufweisen: kann etwas global wie sein disabled, idusw.) Winkelfehler warf? Warum funktioniert es für @Input, aber nicht für @Output? Außerdem versuche ich, einen Weg zu finden, um Fehler zu warnen / zu werfen, wenn ein nicht vorhandener Fehler übergeben @Outputwird.
dev_054

@ dev_054 Dies liegt daran, dass der Satz von Eigenschaften durch die vorhandenen Eigenschaften eines DOM-Elements, einer Direktive oder einer Komponente begrenzt ist, sodass Angular leicht überprüfen kann, ob diese Eigenschaft vorhanden ist oder nicht. Ereignisse hingegen sind mit gebunden addEventListener(ich werde meiner Antwort einige Links hinzufügen, um sie anzuzeigen). Ich denke, es wurde absichtlich gemacht, damit die Entwickler die Ereignisbindung mit ihren eigenen benutzerdefinierten Ereignissen verwenden können. Ich glaube, es gibt keine Möglichkeit, dieses Verhalten beim Kompilieren zu deaktivieren. Obwohl einige IDEs (wie IntelliJ Idea) solche Orte hervorheben und Warnungen anzeigen können.
Kirill Simonov

@ dev_054 Denken Sie daran, dass Sie auch eine Einwegbindung für HTML-Attribute verwenden [attr.any-attribute]können. In diesem Fall wird auch kein Fehler ausgegeben .
Kirill Simonov

0

Es gibt keine direkte Lösung für Ihr Problem, jedoch können einige Fälle abgedeckt werden.

  1. Wenn Sie eine Ausgabe haben, die an 100% von Orten wie dem Schaltflächenereignis verwendet clickwird, können Sie sie in den Selektor aufnehmen, d selector: 'app-test[selectionChange]'. H. Sie können dies auch zum Beispiel tun: selector: 'app-test[selectionChange]', app-test[click]'Bedeutung clickoder selectionChangeerforderlich.
  2. Wenn Sie Code umgestalten und die Ausgabe umbenennen, dh selectionChangein selectedChange, können Sie diesen Selektor verwenden: selector: 'app-test:not([selectionChange])'um Benutzer zum Aktualisieren zu zwingen.

-4

Wenn Sie VS-Code verwenden, können Sie diese Erweiterung installieren: Angular Language Service gibt eine Warnung aus, wenn eine Methode oder Eigenschaft nicht definiert ist. Diese Erweiterung funktioniert sowohl mit Ausgängen als auch mit Eingängen (und attrs usw.).

Der Bezeichner 'XXXvalidateProvider' ist nicht definiert.


Ihr Beispiel zeigt einen @Eingang. Denn @OutputAngular Language Service hilft nichts. Lassen Sie mich wissen, wenn ich die Frage klären muss.
dev_054

Bei einem @Outputwird die gleiche Fehlermeldung angezeigt.
srgrcp
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.