Как передать событие от внуков к бабушке и дедушке в современном ангуляре?

Если у меня есть несколько уровней угловых компонентов, как я могу использовать @Output чтобы событие излучало действие от ребенка к прародителю?

Grandparent:

<parent (handleClick)="grandmaHandleClick($event)">
<parent>
...
grandmaHandleClick(event) {
  console.log('grandma knows you clicked')
}

родитель:

<child (handleClick)="handleClick($event)">
</child>

Ребенок:

<div (click)="onClick">Click button
</div>
...
@Output() handleClick = new EventEmitter
onClick() {
  this.handleClick.emit('clicked a button')
}

Я пытаюсь сделать так, чтобы @Output мог углубить детали до нескольких компонентов, как лучше всего это сделать, и не могли бы вы привести пример?

2 ответа

Решение

Там может быть 2 способа:

  1. С помощью @output (не выглядит хорошим вариантом в вашем случае):

бабушка или дедушка

<parent (notifyGrandParent)="grandmaHandleClick($event)">
<parent>
...
grandmaHandleClick(event) {
  console.log('grandma knows you clicked')
}

Родитель:

<child (handleClick)="childEvent($event)">
</child>

@Output() notifyGrandParent= new EventEmitter();
childEvent(event) {
  this.notifyGrandParent.emit('event')
}

Child правильно реализован в коде, так что хорошо идти.

  1. С помощью BehaviorSubject через Service: С таким большим уровнем вложенности вы можете создать такой сервис, как EventService, а затем создать BehaviorSubject который может быть напрямую подписан на GrandParent. Кроме того, чтобы сделать это service более конкретный компонент, вы можете сохранить эту услугу в module который будет иметь 3 других компонента (GrandParent, Parent и Child)
export class EventService{

 private childClickedEvent = new BehaviorSubject<string>('');

  emitChildEvent(msg: string){
     this.childClickedEvent.next(msg)
  }

  childEventListner(){
     return this.childClickedEvent.asObservable();
   } 

}

а затем в components:

ChildComponent

export class ChildComponent{
   constructor(private evtSvc: EventService){}

   onClick(){
     this.evtSvc.emitChildEvent('clicked a button')
   }
}

бабушка или дедушка

export class GrandComponent{
   constructor(private evtSvc: EventService){}

   ngOnInit(){
     this.evtSvc.childEventListner().subscribe(info =>{
         console.log(info); // here you get the message from Child component
      })
   }
}

Используйте rxjs/subject, это может быть наблюдателем и наблюдаемым одновременно

Использование:

1.Создать объект недвижимости в сервисе:

import { Subject } from 'rxjs';

export class AuthService {
   loginAccures: Subject<boolean> = new Subject<boolean>();
}

2. Когда происходит событие при использовании дочерней страницы / компонента:

logout(){
  this.authService.loginAccures.next(false);
}

3. И подписаться на тему на родительской странице / компоненте:

constructor(private authService: AuthService) {
    this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {this.isLoggedIn = isLoggedIn;})
}

Для этого есть замечательная библиотека под названием ng-interconnect. Вы можете отправить событие из любого компонента в любой компонент, используя эту библиотеку.

В библиотеке предусмотрено создание -

  • Вещатели - одна точка сообщения, которая отправляет несколько событий множеству получателей.

  • Слушатели - одна точка сообщения, которая прослушивает несколько подключений

let messageStream: IMessageStream = createBroadcaster('home/stateChanged');   //Create a broadcaster```
 
 ...
 ...
 /*Receive from it from another component somewhere in the hierarchy*/
 
 let userReceiver = receiveFrom('home/stateChanged', 'contacts/user', (data, error, complete) => {
  console.log(data);
  console.log(error);
  console.log(complete);
 })
 
 
 '''
 '''
 /*Broadcast messages from the first component*/
 nessageStream.emit('logged-in');
Другие вопросы по тегам