如何以现代角度从孙辈到祖父母发出事件?

use*_*582 19 javascript events typescript angular

如果我有多个级别的角度组件,我如何使用@Output事件从子级到祖父级发出动作?

祖父母:

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

家长:

<child (handleClick)="handleClick($event)">
</child>
Run Code Online (Sandbox Code Playgroud)

孩子:

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

我试图拥有它,以便@Output 可以深入钻取一些组件,实现此目的的最佳方法是什么,您能否提供示例?

Sha*_*vek 25

可能有2种方式:

  1. 使用@output

祖父母

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

家长

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

@Output() notifyGrandParent= new EventEmitter();
childEvent(event) {
  this.notifyGrandParent.emit('event')
}
Run Code Online (Sandbox Code Playgroud)

Child在代码中正确实现,所以很好。

  1. 使用BehaviorSubjectvia 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();
   } 

}
Run Code Online (Sandbox Code Playgroud)

然后在components

子组件

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

   onClick(){
     this.evtSvc.emitChildEvent('clicked a button')
   }
}
Run Code Online (Sandbox Code Playgroud)

祖父母

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

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

请注意,通过@output事件,您创建了组件的紧密耦合,因此创建了强依赖项(parent-child-grandchild)。如果该组件不可重用,并且仅为此目的而创建,那么@output这也是有意义的,因为它将向任何新开发人员传达他们具有父子关系的消息。

创建服务来传递数据也暴露了数据到可以注入其他部件service constructor

因此,应该相应地做出决定


小智 5

使用rxjs/subject,可以同时成为观察者和可观察者。

用法:

  1. 在服务中创建主题属性:
import { Subject } from 'rxjs';

export class AuthService {
  loginAccures: Subject<boolean> = new Subject<boolean>();
}
Run Code Online (Sandbox Code Playgroud)
  1. 当事件发生在子页面/组件使用中时:
logout() {
  this.authService.loginAccures.next(false);
}
Run Code Online (Sandbox Code Playgroud)
  1. 并订阅父页面/组件中的主题:
constructor(private authService: AuthService) {
  this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {
    this.isLoggedIn = isLoggedIn;
  })
}
Run Code Online (Sandbox Code Playgroud)