Angular EventEmitter не работает в обратном вызове

У меня несколько странная проблема с EventEmitter в классе. Хотя у меня есть несколько идей, как обойти эту проблему, я хотел бы спросить вас, есть ли у вас идея напрямую решить мою проблему.

Краткое резюме

У меня есть родительский и дочерний компоненты. Родительский компонент хотел бы получать уведомление, когда что-то в дочернем было изменено.

Внутри дочернего элемента у нас есть кнопка. При щелчке он выполняет HTTP-запрос, который изменяет данные. В части кода subscribe я хотел бы сообщить родительскому классу, что что-то было сделано.

Это ломает идею и работает так, как ожидалось: https://stackblitz.com/edit/angular-l7hafr < / а>

Проблема

В моем приложении событие дочернего компонента никогда не генерируется, пока оно выполняется в subscribe запроса http. Если я испущу событие раньше (вне функции подписки), оно будет работать должным образом.

Что я пробовал

Я пытался найти причину. Проблема в том, что мне просто не удается изолировать проблему. Приведенный выше Stackblitz работает так, как ожидалось, а в моем приложении - нет.

В других сообщениях, связанных с этим вопросом, предлагалось выполнить .emit() в бегуне NgZone следующим образом:

this.ngZone.run(() => {
  console.log(NgZone.isInAngularZone());
  this.dataHasChanged.emit();
});

Я реализовал это в обратном вызове подписки, но в результате консоль регистрирует true, но тестовое событие все еще никогда не генерируется.

Как это вообще возможно? Что я могу сделать?


РЕДАКТИРОВАТЬ

Итак, я наконец смог изолировать проблему, и это продемонстрировано в этом очень маленьком примере: https://stackblitz.com/edit/angular-46pndy.

Причина всех проблем в getter для массива. Почему здесь возникает проблема?


person andreas    schedule 18.09.2019    source источник
comment
Вы говорите примерно то же самое. Чем отличается ваше приложение?   -  person Fabian Beyerlein    schedule 18.09.2019
comment
ваш пример stackblitz, кажется, успешно излучается при каждом нажатии кнопки, в чем проблема?   -  person Nitsan Baleli    schedule 18.09.2019
comment
Если ваше приложение не ведет себя как демонстрация stackblitz, вы должны включить соответствующий код вашего приложения в вопрос (разметка HTML + код компонента).   -  person ConnorsFan    schedule 18.09.2019
comment
Соответствующий код включить довольно сложно, поэтому я попробовал минимальный пример. Но похоже, что нет очевидного решения или проблемы, поэтому я скоро обновлю сообщение!   -  person andreas    schedule 18.09.2019
comment
Я добавил информацию с помощью нового Stackblitz. Вы знаете, почему геттер вызывает здесь все эти проблемы? Есть ли причина или это вообще ошибка?   -  person andreas    schedule 18.09.2019
comment
Проблема с вашим примером stackblitz заключается в том, что он выдает ошибку CORS, поэтому вы все время видите ответ как ложный. Если вы замените URL-адрес чем-то вроде jsonplaceholder.typicode.com/posts/1, он будет работать просто отлично. Вы должны добавить несколько регистраторов в свою подписку, чтобы проверить, получаете ли вы данные.   -  person saNiks    schedule 18.09.2019
comment
@saNiks А вот нижние кнопки работают даже при ошибках CORS. И с вашим URL верхние кнопки все еще не работают   -  person Fabian Beyerlein    schedule 18.09.2019
comment
CORS - это не проблема. Я просто хотел использовать случайный HTTP-запрос. Проблема в обратном вызове.   -  person andreas    schedule 18.09.2019


Ответы (1)


Я думаю, что это может быть странное поведение с обнаружением изменений Angular. Если вы отключите обнаружение изменений, событие будет получено.

На самом деле здесь происходит то, что EventEmitter фактически не имеет подписчиков, когда вы используете геттер для создания кнопок. Отключение обнаружения изменений решает проблему, но, вероятно, вызывает другие побочные эффекты в вашем приложении.

Этот StackBlitz демонстрирует один из обходных путей, описанных при использовании чистого канала.

Пример StackBlitz: здесь

Проблемы с GitHub:
angular / angular / issues / 6057
angular / angular / issues / 5918

person Fabian Beyerlein    schedule 18.09.2019