Vérifiez si la sortie est présente sur le composant

14

Considérez le composant suivant:

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

Avec l'appel:

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

Notez que j'ai écrit à la selectedChangeplace du nom de sortie correct selectionChange. L'angulaire 9 avec le drapeau strictTemplatesactivé ne m'a pas du tout aidé. Il a échoué en silence. La partie intéressante est que si je fais la même chose pour @Input, l'application détecte les erreurs et ne compile pas.

Existe-t-il un moyen de lancer une erreur si j'essaie «d'écouter» un fichier inexistant @Output?

dev_054
la source
1
y a-t-il eu des erreurs avec les versions précédentes d'Angular? Je pense que cela n'a jamais jeté d'erreur
Aravind
@Aravind non, il n'a jamais généré d'erreurs. Je demande si c'est possible. Merci d'avance.
dev_054
pourquoi voulez-vous lancer une erreur? y a-t-il un besoin spécifique? J'essaie de comprendre votre question
Aravind
@Aravind, je travaille sur une application d'entreprise avec de nombreux développeurs, il est donc important d'avoir une sorte d'information / d'avertissement / d'erreur. Parfois, quelqu'un change / supprime une @Output()dans une bibliothèque partagée, ou même sur l'application et oublie de supprimer les appels ... et comme nous n'avons pas d'erreurs de compilation, comme nous l'avons fait pour @Input(), nous ne pouvons pas trouver exactement ce qui cause certains problèmes (ou même pour ne pas garder les ordures dans le code). Des tests unitaires pourraient être utiles? Peut-être, mais à l'époque ce n'est pas encore possible à cause du temps.
dev_054

Réponses:

3

Il n'y a pas d' erreur lancée parce que l' événement de liaison dans angulaire est utilisé non seulement avec @Outputs et EventEmitters, mais aussi d'écouter les événements DOM tels que click, keyup, etc. Il pourrait même être utilisé pour écouter les événements personnalisés . Par exemple, si vous créez et émettez un événement personnalisé dans le composant enfant:

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

Ensuite, dans le composant parent, vous pouvez l'attraper par son nom:

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

Angular utilise target.addEventListener (type, écouteur [, options]); en interne (vous pouvez vous en assurer en consultant les liens ci-dessous), où typepourrait être n'importe quelle chaîne.

C'est pourquoi il ne lève aucune exception s'il ne trouve pas de @Outputs correspondant .

listenToElementOutputs

DefaultDomRenderer2.listen

EventManager.addEventListener

DomEventsPlugin.addEventListener

Kirill Simonov
la source
Hé @Kirill Simonov merci pour votre réponse! Eh bien, en prenant votre déclaration: "Il n'y a pas d'erreur levée car la liaison d'événement dans Angular est utilisée non seulement avec @Outputs et EventEmitters, mais aussi pour écouter les événements DOM tels que le clic, la frappe, etc.", pourquoi alors si vous passez un inexistant @Input()(rappelez - vous que les entrées ont les mêmes caractéristiques: peut être quelque chose comme global disabled, idetc.) angulaire erreurs jeté? Pourquoi ça marche @Input, mais pas pour @Output? En outre, j'essaie de trouver un moyen d'avertir / de lancer une erreur si une inexistante @Outputest passée.
dev_054
@ dev_054 c'est parce que l'ensemble des propriétés est limité par les propriétés existantes d'un élément, d'une directive ou d'un composant DOM, donc Angular peut facilement vérifier si cette propriété existe ou non. Les événements, d'autre part, sont liés à l'aide addEventListener(je vais ajouter quelques liens à ma réponse pour le montrer). Je pense que cela a été fait intentionnellement, afin que les développeurs puissent utiliser la liaison d'événements avec leurs propres événements personnalisés. Je crois qu'il n'y a aucun moyen de désactiver ce comportement au moment de la compilation. Bien que certains IDE (comme IntelliJ Idea) puissent mettre en évidence de tels endroits et afficher des avertissements.
Kirill Simonov
@ dev_054 rappelez-vous que vous pouvez également utiliser la liaison unidirectionnelle pour les attributs HTML en utilisant [attr.any-attribute], dans ce cas, aucune erreur ne sera générée non plus.
Kirill Simonov
0

Il n'y a pas de solution directe à votre problème, mais certains cas peuvent être couverts.

  1. Si vous avez une sortie utilisée dans 100% des endroits comme un clickévénement de bouton , vous pouvez l'intégrer au sélecteur, c'est-à-dire selector: 'app-test[selectionChange]'. Vous pouvez également le faire par exemple: selector: 'app-test[selectionChange]', app-test[click]'signifiant clickou selectionChangeest requis.
  2. Si vous refactorisez le code et renommez la sortie, c.- selectionChangeà - d., selectedChangeVous pouvez utiliser ce sélecteur: selector: 'app-test:not([selectionChange])'pour forcer les utilisateurs à mettre à jour.
kemsky
la source
-4

Si vous utilisez VS Code, vous pouvez installer cette extension: Angular Language Service émet un avertissement lorsqu'une méthode ou une propriété n'est pas définie. Cette extension fonctionne à la fois avec les sorties et les entrées (et attrs, etc ...).

L'identifiant «XXXvalidateProvider» n'est pas défini.

srgrcp
la source
Votre exemple montre un @Input. Car @Output, Angular Language Service n'aide en rien. Faites-moi savoir si vous avez besoin de moi pour clarifier la question.
dev_054
Pour un, @Outputvous verrez le même message d'erreur.
srgrcp