【问题标题】:How to emit an event from child to parent to another child?如何将事件从孩子发送到父母再到另一个孩子?
【发布时间】:2022-11-15 21:35:34
【问题描述】:

我有一个从表单获取一些数据的子组件。并通过 @Output 装饰器将其传递给父组件。按下按钮会触发 getDataFromForm()

export class FormChildComponent {

    @Output() doSomethingWithData: EventEmitter<any> = new EventEmitter<any>()

    ...

    getDataFromForm(){
        ...

        this.doSomethingWithData.emit(form.values);
        
    }
    renderSomething(?data){
       //This needs to be called in anther child after the event got 
       triggered and the data got processed in the parent

    }

}

在父组件中,我正在对子组件中的按钮按下事件进行一些数据处理。之后我必须根据另一个孩子中处理过的数据渲染一些东西,这是与上面相同的子组件类型。

父组件.html

<FormChildComponent (doSomethingWithData)="processData($event)">

父组件.ts

processData($event: object){
    
    doSomething($event);

} 

在孩子和父母之间传递事件和数据的最佳做法是什么?

【问题讨论】:

    标签: angular typescript events rxjs


    【解决方案1】:

    您应该只在子项上定义一个变量并使用 @Input() 装饰器。 例如:@Input() prop: YourType;

    然后,您可以使用以下方法将数据从父级传递给子级:

    <FormChildComponent [prop]="dataToPassToChild" (doSomethingWithData)="processData($event)">
    

    这通常是将数据从父组件传递到子组件的最佳实践。另一种方法已经包含在您的问题中(使用@Output()装饰器)。

    在某些情况下,您希望以独立状态提取某些属性。您应该使用服务来实现此目的。

    【讨论】:

    • 我需要在父组件收到并处理来自另一个子组件的数据后立即在子组件中触发一个函数。我不确定道具是否足够。
    • 您也可以在父组件中将此 prop 定义为 Subject 并在子组件中订阅它。这样在主题上调用.next 将导致调用订阅函数。
    【解决方案2】:

    处理多个组件上的输入和输出可能会变得混乱,我更喜欢只创建一个服务来发出和订阅事件。

    @Injectable({ providedIn: 'root' })
    export class MyService {
      dataSubject = new Subject<DataType>();
    }
    

    只需在需要的地方注入服务,在主题上调用 next 以发出事件,然后订阅要对事件采取行动的主题。

    发射

    export class ChildOneComponent {
      data = 'someData';
    
      constructor(private myService: MyService) {}
    
      emit() {
        this.myService.dataSubject.next(this.data);
      }
    }
    

    对事件采取行动

    export class ChildTwoComponent {
      subscription = new Subscription();
    
      constructor(private myService: MyService) {}
    
      ngOnInit() {
        this.subscription = this.myService.dataSubject.subscribe(this.processData);
      }
    
      processData(data: DataType) {
        console.log('Got: ', data);
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    }
    

    我知道你说子组件是相同类型的,所以我不确定你的代码到底是什么样子,考虑到这些组件正在做两件不同的事情。您可能需要详细说明。

    是两个相互订阅的组件吗?这是一个组件订阅另一个组件但反之亦然的一种方式吗?是相互任意订阅的组件列表吗?等等

    【讨论】:

      猜你喜欢
      • 2018-02-07
      • 2021-11-09
      • 1970-01-01
      • 2018-05-22
      • 2018-06-29
      • 2017-03-07
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      相关资源
      最近更新 更多