简体   繁体   English

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

[英]How to emit an event from grandchildren to grandparent in modern angular?

If I have multiple levels of angular components, how can I use @Output to emit an event from child to the grand parent?如果我有多个级别的角度组件,如何使用@Output将事件从子级发送到@Output

Grandparent:祖父母:

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

Parent:家长:

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

Child:孩子:

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

I am trying to have it so that @Output can prop drill a few components deep, whats the best way to accomplish this, and can you provide example?我试图拥有它,以便@Output 可以深入钻取一些组件,实现此目的的最佳方法是什么,您能否提供示例?

There could be 2 ways:可能有2种方式:

  1. Using @output :使用@output

Grandparent祖父母

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

Parent :家长

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

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

Child is implemented properly in the code so it is good to go. Child在代码中正确实现,所以很好。

  1. Using BehaviorSubject via Service : With this much level of nesting, you can actually create some service like EventService , and then create BehaviorSubject which can directly be subscribed by the GrandParent.使用BehaviorSubject通过Service :筑巢的这么多的水平,实际上就可以创建像一些服务EventService ,然后创建BehaviorSubject可以直接由祖父母来认购。 Also, to make this service more component specific, you can keep this service in a module which will have other 3 components (GrandParent, Parent and Child)此外,为了使此service更加具体,您可以将此服务保留在一个module ,该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();
   } 

}

and then in components :然后在components

ChildComponent子组件

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

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

GrandParent祖父母

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

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

Please note that, with @output event, you create a tight coupling of components and so a strong dependency ( parent-child-grandchild ) is created.请注意,使用@output事件,您创建了组件的紧密耦合,因此创建了强依赖项( parent-child-grandchild )。 If the component are not reusable and are only created to serve this purpose, then @output will also make sense because it'll convey the message to any new developer that they have parent-child relationship.如果该组件不可重用且仅为此目的而创建,那么@output也将有意义,因为它将向任何新开发人员传达他们具有父子关系的消息。

Creating a service to pass data also exposes the data to other components which can inject service in constructor .创建传递数据的服务也会将数据暴露给其他组件,这些组件可以在constructor注入service

So, the decision should be taken accordingly .因此,应该相应地做出决定

Use rxjs/subject, it can be observer and observable in the same time.使用rxjs/subject,可以同时被观察者和被观察者。

Usage:用法:

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

export class AuthService {
  loginAccures: Subject<boolean> = new Subject<boolean>();
}
  1. When event happens in child page/component use:当事件在子页面/组件中发生时使用:
logout() {
  this.authService.loginAccures.next(false);
}
  1. And subscribe to subject in parent page/component:并订阅父页面/组件中的主题:
constructor(private authService: AuthService) {
  this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {
    this.isLoggedIn = isLoggedIn;
  })
}

There is a wonderful library called ng-interconnect for this purpose.为此,有一个名为ng-interconnect的很棒的库。 You can emit an event from any component to any component using this library.您可以使用此库从任何组件向任何组件发出事件。

The library provide for creating -图书馆提供创建 -

  • Broadcasters - one message point that send multiple events to many receivers广播器 - 一个消息点,将多个事件发送到多个接收器

  • Listeners - one message point which listens from multiple connections侦听器 - 从多个连接侦听的一个消息点

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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM