Проверьте, присутствует ли выход на компоненте

14

Рассмотрим следующий компонент:

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

С звонком:

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

Обратите внимание, что я написал selectedChangeвместо правильного выходного имени selectionChange. Angular 9 с strictTemplatesвключенным флагом мне совсем не помог. Это молча провалилось. Интересно то, что если я делаю то же самое @Input, приложение ловит ошибки и не компилируется.

Есть ли способ выдать ошибку, если я попытаюсь «прослушать» несуществующее @Output?

dev_054
источник
1
были ли ошибки в предыдущих версиях Angular? Я думаю, что это никогда не бросало никакой ошибки в этом
Аравинд
@Aravind нет, это никогда не бросало ошибки. Я спрашиваю, возможно ли это. Заранее спасибо.
dev_054
почему вы хотите выбросить ошибку? есть ли конкретная необходимость? Я пытаюсь понять твой вопрос
Аравинд
@Aravind, я работаю над корпоративным приложением со многими разработчиками, поэтому важно иметь какую-то информацию / предупреждение / ошибку. Иногда кто-то меняет / удаляет @Output()в общей библиотеке или даже в приложении и забывает удалять вызовы ... и, поскольку у нас нет ошибок компиляции, как у нас @Input(), мы не можем точно найти, что вызывает определенные проблемы (или даже для того, чтобы не хранить мусор в коде). Модульные тесты могут быть полезны? Возможно, но пока невозможно из-за времени.
dev_054

Ответы:

3

Не выдается никакой ошибки, поскольку привязка событий в Angular используется не только с @Outputs и EventEmitters, но и для прослушивания событий DOM, таких как click, keyupи т. Д. Его можно даже использовать для прослушивания пользовательских событий . Например, если вы создаете и отправляете пользовательское событие в дочернем компоненте:

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

Затем в родительском компоненте вы можете поймать его по имени:

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

Angular использует target.addEventListener (type, listener [, options]); внутренне (вы можете убедиться в этом, посмотрев ссылки ниже), где typeможет быть любая строка.

Вот почему он не выдает никаких исключений, если не находит подходящих @Outputs.

listenToElementOutputs

DefaultDomRenderer2.listen

EventManager.addEventListener

DomEventsPlugin.addEventListener

Кирилл Симонов
источник
Привет, @Kirill Simonov спасибо за ваш ответ! Что ж, примите ваше утверждение: «Нет ошибки, потому что привязка событий в Angular используется не только с @Outputs и EventEmitters, но и для прослушивания событий DOM, таких как click, keyup и т. Д.», Почему тогда, если вы передадите несуществующие @Input()(помните , что входы имеют одинаковые характеристики: может быть что - то глобальное , как disabled, idи т.д.) угловые кинула ошибки? Почему это работает @Input, а не для @Output? Кроме того, я пытаюсь найти способ предупредить / выбросить ошибку, если пропущено несуществующее @Output.
dev_054
@ dev_054 это потому, что набор свойств ограничен существующими свойствами элемента, директивы или компонента DOM, поэтому Angular может легко проверить, существует это свойство или нет. События, с другой стороны, связаны с помощью addEventListener(я добавлю несколько ссылок на мой ответ, чтобы показать его). Я думаю, это было сделано намеренно, поэтому разработчики могли использовать привязку событий со своими собственными событиями. Я считаю, что нет способа отключить это поведение во время компиляции. Хотя некоторые IDE (например, IntelliJ Idea) могут выделять такие места и отображать предупреждения.
Кирилл Симонов
@ dev_054 помните , что вы также можете использовать одностороннее связывание для HTML атрибутов с использованием [attr.any-attribute], в этом случае ошибка не будет выброшен либо.
Кирилл Симонов
0

Прямого решения вашей проблемы не существует, однако некоторые случаи могут быть рассмотрены.

  1. Если у вас есть какой - либо вывод , который используется в 100% таких местах , как кнопка clickсобытие , то вы можете сделать его частью селектора есть selector: 'app-test[selectionChange]'. Также вы можете сделать это, например: selector: 'app-test[selectionChange]', app-test[click]'значение clickили selectionChangeтребуется.
  2. Если вы рефакторинг кода и вывод переименования ИЭ selectionChangeв selectedChangeто вы можете использовать этот селектор: selector: 'app-test:not([selectionChange])'пользователь силы для обновления.
Кемский
источник
-4

Если вы используете VS Code, вы можете установить это расширение: Angular Language Service выдаст предупреждение, если метод или свойство не определены. Это расширение работает с обоими выходами и входами (и attrs, и т. Д.).

Идентификатор «XXXvalidateProvider» не определен.

srgrcp
источник
Ваш пример показывает @Input. Ибо @OutputAngular Language Service ни в чем не помогает. Дайте мне знать, если вам нужно, чтобы я уточнил вопрос.
dev_054
Для @Outputвы увидите то же сообщение об ошибке.
srgrcp