Как передать событие от внуков к бабушке и дедушке в современном ангуляре?
Если у меня есть несколько уровней угловых компонентов, как я могу использовать @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 способа:
- С помощью
@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 правильно реализован в коде, так что хорошо идти.
- С помощью
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');