【问题标题】:How to let component.ts load all response before loading template?如何让component.ts在加载模板之前加载所有响应?
【发布时间】:2019-11-27 08:38:21
【问题描述】:

我想从 component.ts 文件中加载所有函数的响应,然后让模板查看该数据。

我的 ngOnInit 函数中有 3 个函数,它们可以得到我用来在模板中加载它的响应。

    ngOnInit() {
        this.getSong();
        this.getAllSongs();
        this.getProjects();
    }

    // get Latest Song
    getSong() {
        this.amen.getSongs(this.singleSongParam).subscribe(
            (response) => {
                this.handleSongResponse(response);
            },
            (error) => {
                this.error = error.error.errors;
            }
        );
    }

    getAllSongs() {
        this.amen.getSongs(this.allSongsParam).subscribe(
            (response) => {
                this.handleSongsResponse(response);
            },
            (error) => {
                this.error = error.error.errors;
            }
        );
    }

    getProjects() {
        this.amen.getProjects(this.projectsParam).subscribe(
            (response) => {
                this.handleProjectsResponse(response);
            },
            (error) => {
                this.error = error.error.errors;
            }
        );
    }

也许我使用async/await,但不知道如何在订阅中使用它...如果有任何方法可以做到这一点,请提供帮助。

【问题讨论】:

  • 你试过解决方案了吗?

标签: angular


【解决方案1】:

您可以在.ts中使用forkJoin,在模板中使用*ngIf来实现。

试试这样:

.ts

  loadTemplate: false;

  ngOnInit() {

    const request1 = this.getSong();
    const request2 = this.getAllSongs();
    const request3 = this.getProjects();

    forkJoin([request1, request2, request3]).subscribe(data => {
      this.loadTemplate = true;
    });
  }

.html

<ng-container *ngIf="loadTemplate">
  ...
</ng-container>

【讨论】:

  • 这是实现这一目标的最佳方式。仅供参考,如果您使用 forkJoin 并且您的任何 api 失败,那么这将是完全失败。为此,您可以单独捕获并相应地处理
  • @SiddharthPal 我同意。像这样的情况是可以处理的。
  • @AdritaSharma 在使用 forkJoin 后无法在我的情况下工作,我的组件未加载到页面上。
  • console.log(data[0]), 1 和 2
【解决方案2】:

收到响应后使用 *ngIf 显示模板

【讨论】:

    【解决方案3】:

    您可以使用forkjoin。 Fork join 并行执行所有请求操作和 end join 结果。代码是这样的:

    this.registrationSubscriptionForkJoin = forkJoin([this.service1, this.service2...]).subscribe(response => {
                      this.listresulserivce1 = response[0];
                      this.listresultservice2= response[1];
                    }
    

    您可以使用您的方法在ngOnInit 中调用 forkjoin

    【讨论】:

    • 但是这里的模板会在得到响应之前被加载
    • 不,您可以使用 *ngif,您必须指定 if (this.listresultserice1!=null" 加载模板。因此,当计算列表时,会显示模板
    • 所以 *ngIf 是必需的,没有我们可以实现的任何方式
    • 我们可以创建一个组件,在得到服务响应后,在运行时将其注入到视图中
    • 是的!是的,您必须使用 *ngIf 因为模板总是在 .ts 调用所有服务之后加载。因此,如果您在 ngif 中使用的列表未加载,则当列表不为空时,不会显示模板
    【解决方案4】:

    一种解决方法是,在组件中创建一个字段,并在获得所有响应后将其设置为 true。在带有*ngIf 条件的模板中使用此字段。

    【讨论】:

      【解决方案5】:
      【解决方案6】:

      方法一:简单使用forkJoin和*ngIf

      Live demo

      *ngIf 用法

      <div *ngIf="condition">Content to render when condition is true.</div>
      

      forkJoin 用法

        ngOnInit() {
          // simulate 3 requests with different delays
          forkJoin(
            this._myService.makeRequest('Request One', 2000),
            this._myService.makeRequest('Request Two', 1000),
            this._myService.makeRequest('Request Three', 3000)
          )
          .subscribe(([res1, res2, res3]) => {
            this.propOne = res1;
            this.propTwo = res2;
            this.propThree = res3;
          });
        }
      

      方法二:使用解析接口

      Live demo

      解决使用问题

      @Injectable({ providedIn: 'root' })
      export class HeroResolver implements Resolve<Hero> {
        constructor(private service: HeroService) {}
      
        resolve(
          route: ActivatedRouteSnapshot,
          state: RouterStateSnapshot
        ): Observable<any>|Promise<any>|any {
          return forkJoin(
             this.service.getHero1(),
             this.service.getHero2(),
             this.service.getHero3(),
          );
        }
      }
      
      @NgModule({
        imports: [
          RouterModule.forRoot([
            {
              path: 'detail/:id',
              component: HeroDetailComponent,
              resolve: {
                hero: HeroResolver
              }
            }
          ])
        ],
        exports: [RouterModule]
      })
      export class AppRoutingModule {}
      

      参考

      rxjs - forkJoin

      Angular - *ngIf

      Angular - Resolve

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多