Не існує еквівалента $scope.emit()
або $scope.broadcast()
з AngularJS. EventEmitter всередині компонента наближається, але, як ви вже згадували, він посилатиме лише подію безпосередньо безпосередньому батьківському компоненту.
У Angular є інші альтернативи, які я спробую пояснити нижче.
Прив'язки @ Input () дозволяють підключати модель програми у графіці спрямованого об'єкта (корінь до листя). Типовою поведінкою стратегії детектора змін компонента є розповсюдження всіх змін у моделі програми для всіх прив’язок будь-якого підключеного компонента.
Убік: Є два типи моделей: Перегляд моделей та Моделів додатків. Модель програми підключається через прив'язки @Input (). Модель перегляду - це просто властивість компонента (не прикрашена @Input ()), яка пов'язана у шаблоні компонента.
Щоб відповісти на ваші запитання:
Що робити, якщо мені потрібно зв’язатися між компонентами братів і сестер?
Модель спільної програми : Брати та сестри можуть спілкуватися через спільну модель програми (як і кутова 1). Наприклад, коли один брат побратимів вносить зміни до моделі, інший брат, який має прив’язки до тієї ж моделі, автоматично оновлюється.
Події компонента : Дочірні компоненти можуть передавати подію батьківському компоненту, використовуючи прив'язки @Output (). Батьківський компонент може обробляти подію та маніпулювати моделлю програми або власною моделлю перегляду. Зміни до прикладної моделі автоматично поширюються на всі компоненти, які прямо чи опосередковано пов'язуються з тією ж моделлю.
Сервісні події : Компоненти можуть підписатися на сервісні події. Наприклад, два компоненти братів можуть брати підписку на одну службову подію та відповідати, змінюючи відповідні моделі. Детальніше про це нижче.
Як я можу зв’язатись між компонентом Root та компонентом, вкладеним у кілька рівнів глибоко?
- Спільна модель програми : Модель програми може бути передана від компонента Root вниз до глибоко вкладених підкомпонентів через прив'язки @Input (). Зміни в моделі з будь-якого компонента автоматично поширюються на всі компоненти, які мають одну і ту ж модель.
- Службові події : Ви також можете перемістити EventEmitter до спільної служби, яка дозволяє будь-якому компоненту вводити послугу та підписуватися на подію. Таким чином, компонент Root може викликати метод обслуговування (як правило, мутує модель), який, в свою чергу, випромінює подію. Кілька шарів вниз, компонент онука, який також вводив послугу і підписався на ту саму подію, може впоратися з нею. Будь-який обробник подій, який змінить спільну модель програми, автоматично поширюється на всі компоненти, що залежать від неї. Це, мабуть, найближчий еквівалент
$scope.broadcast()
з кутового 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));
}
}
Довідка: Визначення змін у кутових