【问题标题】:Angular: Call parent component function when all child components complete data loadAngular:当所有子组件完成数据加载时调用父组件函数
【发布时间】:2020-07-15 14:42:39
【问题描述】:

我正在使用 Angular6,但我陷入了这样一种情况:我有一个父组件(比如父组件),它有 3 个子组件(比如 child1、child2、child3)。 parent-component.html 看起来像这样:

<div>
  <child1></child1>
  <child2></child2>
  <child3></child3>
</div>

所有子组件调用它们的服务(反过来从 http API 获取数据)并加载它们自己的数据。所有组件都有不同的数据加载时间(比如 child1 有 1 秒,child2 有 2 秒,child3 有 3 秒)。

当所有三个子组件都加载了他们从服务中获得的数据时,我想在 paren 中执行一个函数。

【问题讨论】:

    标签: angular rxjs angular6


    【解决方案1】:

    您可以向子组件添加一个输出方法,以便在加载数据时发出,就像这样,

    child.ts

    import { Component, Output, EventEmitter } from '@angular/core';
    import { Observable } from 'rxjs';
    
    @Component({
      selector: 'app-childx',
      templateUrl: './childx.component.html',
      styleUrls: ['./childx.component.scss']
    })
    export class Childx {
      data: Data;
      // output
      @Output() dataLoaded = new EventEmitter<string>();
    
      constructor() { }
    
      ngOnInit() {
        // emit after loading data
      }
    
      emit() {
        this.dataLoaded.emit('Childx');
      }
    
    }
    

    parent.html

    <div>
      <child1 (dataLoaded)="dataLoaded($event)"></child1>
      <child2 (dataLoaded)="dataLoaded($event)"></child2>
      <child3 (dataLoaded)="dataLoaded($event)"></child3>
    </div>
    

    parent.ts

    childrenDataLoadedCount = 0;
    dataLoaded(child: string) {
      childrenDataLoadedCount++;
      if (childrenDataLoadedCount === 3) {
        // here all children load data
      }
    }
    

    我提出一个非常简单的逻辑只是为了举例说明,您必须根据您的情况添加一些内容。我还使用一个字符串作为孩子的发射参数,它可以是任何东西或什么都没有,在这个简单的例子中它可能什么都没有,但我添加只是为了显示一个可能有用的参数。

    【讨论】:

      【解决方案2】:

      为了简单起见,我假设所有 API 调用都来自同一个服务。如果不是,您可以简单地创建一个所有组件共有的服务并使用它。基本机制将保持不变。

      您可以创建多个主题,这些主题馈送到一个主主题中,父组件可以使用zip 函数以了解后台调用是否结束。试试下面的

      公共服务

      import { zip } from 'rxjs';
      
      @Injectable()
      export class ApiService {
        private apiOneStatusSource = new Subject<boolean>();
        private apiTwoStatusSource = new Subject<boolean>();
        private apiThreeStatusSource = new Subject<boolean>();
      
        private apisStatusSource = new Subject<boolean>();
      
        private apiOneStatus$ = this.apiOneStatusSource.asObservable();
        private apiTwoStatus$ = this.apiOneStatusSource.asObservable();
        private apiThreeStatus$ = this.apiOneStatusSource.asObservable();
      
        private apisStatus$ = this.apisStatusSource.asObservable();
      
        constructor() {
          zip(this.apiOneStatus$, this.apiTwoStatus$, this.apiThreeStatus$).subscribe(    // <-- use `zip` to check if all the observables have been emitted
            statuses => {
              if (statuses.every(status => status === true)) {
                this.apisStatusSource.next(true);
              }
            }
          );
        }
      
        public setApiOneStatus(status: boolean) {
          this.apiOneStatusSource.next(status);
        }
      
        public setApiTwoStatus(status: boolean) {
          this.apiTwoStatusSource.next(status);
        }
      
        public setApiThreeStatus(status: boolean) {
          this.apiThreeStatusSource.next(status);
        }
      
        public getApisStatus() {
          return this.apisStatus$;
        }
      }
      

      父组件

      ngOnInit() {
        this.apiService.getApisStatus.subscribe(
          status => {
            // api from all 3 child compnents have returned values - proceed further
          }
        );
      }
      

      子组件

      this.apiService.componentApiCall().subscribe(
        response => {
          // handle response
          this.apiService.setApiOneStatus(true);    // <-- set corresponding status here: setApiTwoStatus for child 2 and so on...
        },
        error => {
          // handle error
          this.apiService.setApiOneStatus(false);   // <-- set corresponding status here: setApiTwoStatus for child 2 and so on...
      );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-03
        • 2020-12-23
        • 2018-09-12
        • 2020-08-23
        • 2018-07-01
        • 1970-01-01
        • 2017-12-17
        相关资源
        最近更新 更多