angular - 在 Angular 5 中呈现 View 之前等待数据

标签 angular typescript

我是 Angular 5 的新手,能够使用订阅创建可访问服务方法的 View ,但遇到渲染延迟问题。用户看到第一个“未定义”字符串,并在 0.5 秒后更改为正确的值。

这是组件的 .ts 文件:

 public trips: Trip[];
  public numberOfUsers : Map<string, number> = new Map<string, number>();

  constructor(private tripService: TripService) { }

  ngOnInit() {
   this.getTrips();
  }

  getTrips() {
    this.tripService.getTripForMe().subscribe(
      data => { this.trips = data;},
      err => console.error(err),
      () => this.initNumberOfUsers()
    );
  }

  initNumberOfUsers() {
    for (let i = 0; i < this.trips.length; i++) {
      let count;
      this.tripService.getNumberOfUsers().subscribe(
        data => { count = data},
        err => console.error(err),
        () => this.numberOfUsers.set(this.trips[i].id, count)
      );


      ;
    }
  }

  getNumberOfUsers(data) {
    return this.numberOfUsers.get(data.id);
  }

方法 initNumberOfUsers 在第一次订阅完成后被调用,这很好,但是 getNumberOfUsers(data) 可能之前被调用并得到“undefined”。

这是模板中的相关部分(“数据”是 ngFor 循环的当前值):

<span [innerText]="getNumberOfUsers(data)"></span>

有没有办法确保两个订阅方法在渲染之前按顺序完成?

更新

我能够创建解析器并且控制台显示对象,但是我很难将数据传递给组件。

Reolver 代码:

import { Injectable } from '@angular/core';
import { Router, Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Trip} from ....
import { TripService } from .....
import { Observable } from 'rxjs/Rx';

@Injectable()
export class TripsResolve implements Resolve<Trip[]> {

   public trips: Trip[];

   constructor(private service: TripService) {}

   resolve(route: ActivatedRouteSnapshot, 
           state: RouterStateSnapshot) {
     this.service.getTrips().subscribe(
        data => { this.trips = data },
        err => console.error(err),
        () => console.log(this.trips)
      );
      return this.trips;
   }
}

从路线

resolve: {
         trips: TripsResolve
      }

来自模块

providers: [
        ...
        TripsResolve,
        ...

组件中数据未通过/不可用:

import { Component, OnInit } from '@angular/core';
import { Trip } from ...
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: ...
  templateUrl: ...
  styleUrls: ...
})
export class MyComponent implements OnInit {

    public trips: Trip[];

    constructor(private route: ActivatedRoute,
                private router: Router) {
    }

    ngOnInit() {
        this.route.data.forEach(data => {
            this.trips = data.trips;
            console.log(this.trips);  //can't see it
       });

    } 
}

知道如何访问/检索组件中的数据吗?

最佳答案

我在通过 API 调用处理数据时遇到过类似的问题

我尝试了两种解决方案

一个正在使用 *ngIf

只有当数据准备好时,DOM 才会填充。

<div *ngIf="isLoaded">Text to show</div>

另一个是使用解析器,在渲染 View 本身之前它会准备数据。但有时,如果数据加载时间过长,解析器会使您的屏幕保持空白。

@Injectable()
export class HeroDetailResolve implements Resolve {
    constructor(private heroService: HeroService, private router: Router) { }

    resolve(route: ActivatedRouteSnapshot): Promise | boolean {
        let id = +route.params['id'];
        return this.heroService.getHero(id).then(hero => {
            if (hero) {
                return hero;
            } else { // id not found
                this.router.navigate(['/dashboard']);
                return false;
            }
        });
    }
}

所以你现在有两个选择。

我会推荐 *ngIf。在加载数据的过程中,显示​​一些加载程序 gif 或一些消息,让用户知道后台发生了一些事情。

关于angular - 在 Angular 5 中呈现 View 之前等待数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49504266/

相关文章:

Angular 4如何应用动态样式?

angular - amcharts 4 光标和鼠标定位不正确

javascript - 如何通过过滤器显示特定值?

javascript - 如何使用 Angular 数组从formbuilder保存

TypeScript:实现具有调用签名和索引签名的接口(interface)

javascript - NestJS:动态模块的缺点?

javascript - 从angular2中的嵌套文本框获取值

Angular2 - 如何从应用程序外部调用组件功能

javascript - typescript 类 : will class be hoisted when I use two classes?

typescript - 扩展现有的@types 类型定义以包含缺失的属性