Нет ли эквивалента $scope.emit()
или$scope.broadcast()
в Angular?
Я знаю EventEmitter
функциональность, но насколько я понимаю, это будет просто отправлять событие родительскому элементу HTML.
Что делать, если мне нужно общаться между FX. братья или сестры или между компонентом в корне DOM и элементом, вложенным в несколько уровней?
Ответы:
Нет эквивалента
$scope.emit()
или$scope.broadcast()
AngularJS от него. EventEmitter внутри компонента подходит близко, но, как вы упомянули, он отправляет событие только непосредственному родительскому компоненту.В Angular есть другие альтернативы, которые я постараюсь объяснить ниже.
Привязки @Input () позволяют связать модель приложения в графе ориентированных объектов (от корня до листьев). Поведение по умолчанию стратегии детектора изменений компонента заключается в распространении всех изменений в модели приложения для всех привязок из любого подключенного компонента.
Помимо: есть два типа моделей: модели просмотра и прикладные модели. Модель приложения связана через привязки @Input (). Модель представления - это просто свойство компонента (не декорированное @Input ()), которое связано в шаблоне компонента.
Чтобы ответить на ваши вопросы:
Что делать, если мне нужно общаться между родственными компонентами?
Модель общего приложения : братья и сестры могут общаться через модель общего приложения (как в угловом 1). Например, когда один из братьев или сестер вносит изменения в модель, другой брат, имеющий привязки к той же модели, автоматически обновляется.
События компонента . Дочерние компоненты могут отправлять событие родительскому компоненту, используя привязки @Output (). Родительский компонент может обрабатывать событие и манипулировать моделью приложения или его собственной моделью представления. Изменения в модели приложения автоматически распространяются на все компоненты, которые прямо или косвенно связаны с одной и той же моделью.
Сервисные события : Компоненты могут подписаться на сервисные события. Например, два дочерних компонента могут подписаться на одно и то же сервисное событие и ответить, изменив свои соответствующие модели. Подробнее об этом ниже.
Как я могу общаться между корневым компонентом и компонентом, вложенным в несколько уровней?
$scope.broadcast()
из Angular 1. Следующий раздел описывает эту идею более подробно.Пример наблюдаемой службы, которая использует события службы для распространения изменений
Вот пример наблюдаемой службы, которая использует события службы для распространения изменений. Когда добавляется TodoItem, служба генерирует событие, уведомляющее подписчиков компонента.
Вот как корневой компонент будет подписываться на событие:
Дочерний компонент, вложенный в несколько уровней, подписался бы на событие таким же образом:
Вот компонент, который вызывает сервис для запуска события (он может находиться в любом месте дерева компонентов):
Ссылка: Обнаружение изменений в угловых
источник
itemAdded$
. Это соглашение RxJS или что-то? Откуда это?street
свойство модели приложения, но поскольку Angular 2 реализует обнаружение изменений по идентификатору / ссылке, изменения не распространяются (onChanges
не вызывается), поскольку ссылка на модель приложения не изменилась ( продолжение ...)Следующий код в качестве примера замены $ scope.emit () или $ scope.broadcast () в Angular 2 с использованием общего сервиса для обработки событий.
Пример использования:
Broadcast:
Слушатель:
Он может поддерживать несколько аргументов:
источник
off(name, listener) { this.listeners[name] = this.listeners[name].filter(x => x != listener); }
Я использую службу сообщений, которая упаковывает rxjs
Subject
(TypeScript)Пример Plunker: служба сообщений
Компоненты могут подписываться и транслировать события (отправитель):
(приемник)
subscribe
МетодMessageService
возвращает rxjsSubscription
объект, который может быть отписался от примерно так:Также см. Этот ответ: https://stackoverflow.com/a/36782616/1861779
Пример Plunker: служба сообщений
источник
Property 'filter' does not exist on type 'Subject<EventMessage>'.
this.handler.pipe(filter(...))
. Смотрите операторы lettable .return this.handler.pipe( filter(message => message.type === type), map(message => message.payload) ).subscribe(callback);
НЕ используйте EventEmitter для служебного общения.
Вы должны использовать один из наблюдаемых типов. Мне лично нравится BehaviorSubject.
Простой пример:
Вы можете пройти начальное состояние, здесь я пропустил нуль
Когда вы хотите обновить тему
Наблюдайте от любого сервиса или компонента и действуйте, когда он получает новые обновления.
Здесь больше информации. ,
источник
Вы можете использовать
EventEmitter илиobservables для создания службы Eventbus, которую вы регистрируете в DI. Каждый компонент, который хочет участвовать, просто запрашивает службу в качестве параметра конструктора и отправляет и / или подписывается на события.Смотрите также
источник
Мой любимый способ сделать это - использовать объект поведения или источник событий (почти такой же) в моем сервисе для контроля всего моего подкомпонента.
Используя angular cli, запустите ng gs, чтобы создать новый сервис, затем используйте BehaviorSubject или EventEmitter.
Когда вы сделаете это, каждый компонент, использующий вашу службу в качестве поставщика, будет знать об этом изменении. Просто подпишитесь на результат, как вы делаете с eventEmitter;)
источник
Я создал образец pub-sub здесь:
http://www.syntaxsuccess.com/viewarticle/pub-sub-in-angular-2.0
Идея состоит в том, чтобы использовать объекты RxJs для подключения Observer и Observables в качестве общего решения для создания и подписки на пользовательские события. В моем примере я использую объект клиента для демонстрационных целей
Вот также живая демонстрация: http://www.syntaxsuccess.com/angular-2-samples/#/demo/pub-sub
источник
Это моя версия:
использовать:
}
испускают:
источник
Мы реализовали наблюдаемую директиву ngModelChange, которая отправляет все изменения модели через генератор событий, который вы создаете в своем собственном компоненте. Вы просто должны привязать ваш источник событий к директиве.
Видеть: https://github.com/atomicbits/angular2-modelchangeobservable
В html свяжите ваш источник событий (countryChanged в этом примере):
В вашем компоненте машинописи выполните некоторые асинхронные операции над EventEmitter:
источник
Сервисные события: Компоненты могут подписаться на сервисные события. Например, два дочерних компонента могут подписаться на одно и то же сервисное событие и ответить, изменив свои соответствующие модели. Подробнее об этом ниже.
Но обязательно отмените подписку на это при уничтожении родительского компонента.
источник