Нет эквивалента $scope.emit()
или$scope.broadcast()
AngularJS от него. EventEmitter внутри компонента подходит близко, но, как вы упомянули, он отправляет событие только непосредственному родительскому компоненту.
В Angular есть другие альтернативы, которые я постараюсь объяснить ниже.
Привязки @Input () позволяют связать модель приложения в графе ориентированных объектов (от корня до листьев). Поведение по умолчанию стратегии детектора изменений компонента заключается в распространении всех изменений в модели приложения для всех привязок из любого подключенного компонента.
Помимо: есть два типа моделей: модели просмотра и прикладные модели. Модель приложения связана через привязки @Input (). Модель представления - это просто свойство компонента (не декорированное @Input ()), которое связано в шаблоне компонента.
Чтобы ответить на ваши вопросы:
Что делать, если мне нужно общаться между родственными компонентами?
Модель общего приложения : братья и сестры могут общаться через модель общего приложения (как в угловом 1). Например, когда один из братьев или сестер вносит изменения в модель, другой брат, имеющий привязки к той же модели, автоматически обновляется.
События компонента . Дочерние компоненты могут отправлять событие родительскому компоненту, используя привязки @Output (). Родительский компонент может обрабатывать событие и манипулировать моделью приложения или его собственной моделью представления. Изменения в модели приложения автоматически распространяются на все компоненты, которые прямо или косвенно связаны с одной и той же моделью.
Сервисные события : Компоненты могут подписаться на сервисные события. Например, два дочерних компонента могут подписаться на одно и то же сервисное событие и ответить, изменив свои соответствующие модели. Подробнее об этом ниже.
Как я могу общаться между корневым компонентом и компонентом, вложенным в несколько уровней?
- Модель общего приложения : модель приложения может быть передана из корневого компонента в глубоко вложенные подкомпоненты через привязки @Input (). Изменения в модели из любого компонента будут автоматически распространяться на все компоненты, которые используют одну и ту же модель.
- События службы : вы также можете переместить EventEmitter в общую службу, которая позволяет любому компоненту внедрить службу и подписаться на событие. Таким образом, корневой компонент может вызывать метод службы (обычно изменяющий модель), который, в свою очередь, генерирует событие. Несколько уровней вниз, дочерний компонент, который также внедрил службу и подписался на то же событие, может обработать его. Любой обработчик событий, который изменяет общую модель приложения, будет автоматически распространяться на все компоненты, которые зависят от нее. Это, вероятно, самый близкий эквивалент
$scope.broadcast()
из Angular 1. Следующий раздел описывает эту идею более подробно.
Пример наблюдаемой службы, которая использует события службы для распространения изменений
Вот пример наблюдаемой службы, которая использует события службы для распространения изменений. Когда добавляется TodoItem, служба генерирует событие, уведомляющее подписчиков компонента.
export class TodoItem {
constructor(public name: string, public done: boolean) {
}
}
export class TodoService {
public itemAdded$: EventEmitter<TodoItem>;
private todoList: TodoItem[] = [];
constructor() {
this.itemAdded$ = new EventEmitter();
}
public list(): TodoItem[] {
return this.todoList;
}
public add(item: TodoItem): void {
this.todoList.push(item);
this.itemAdded$.emit(item);
}
}
Вот как корневой компонент будет подписываться на событие:
export class RootComponent {
private addedItem: TodoItem;
constructor(todoService: TodoService) {
todoService.itemAdded$.subscribe(item => this.onItemAdded(item));
}
private onItemAdded(item: TodoItem): void {
// do something with added item
this.addedItem = item;
}
}
Дочерний компонент, вложенный в несколько уровней, подписался бы на событие таким же образом:
export class GrandChildComponent {
private addedItem: TodoItem;
constructor(todoService: TodoService) {
todoService.itemAdded$.subscribe(item => this.onItemAdded(item));
}
private onItemAdded(item: TodoItem): void {
// do something with added item
this.addedItem = item;
}
}
Вот компонент, который вызывает сервис для запуска события (он может находиться в любом месте дерева компонентов):
@Component({
selector: 'todo-list',
template: `
<ul>
<li *ngFor="#item of model"> {{ item.name }}
</li>
</ul>
<br />
Add Item <input type="text" #txt /> <button (click)="add(txt.value); txt.value='';">Add</button>
`
})
export class TriggeringComponent{
private model: TodoItem[];
constructor(private todoService: TodoService) {
this.model = todoService.list();
}
add(value: string) {
this.todoService.add(new TodoItem(value, false));
}
}
Ссылка: Обнаружение изменений в угловых