【问题标题】:Angular2 - Make component wait until the service is done fetching data, then render itAngular2 - 让组件等到服务完成获取数据,然后渲染它
【发布时间】:2017-02-14 05:31:04
【问题描述】:

我无法实现一个加载数据(gyms 数组)的服务,然后允许所有其他组件使用它,而不发出其他 HTTP 请求。

如果用户从标题页开始并加载所有数据,我的应用程序工作正常,但是当我转到特定详细信息页面 (.../gym/1) 并重新加载页面时,对象不在服务阵列呢。如何使尝试访问服务数组的组件等到加载数据?更具体地说,如何延迟 GymComponent 中的 gymService.getGym(1) 调用,直到 getAllGymsFromBackEnd() 函数完成填充数组?

我读过关于解析器的文章,但我的修修补补让我无处可去。

任何帮助将不胜感激。

这是我正在处理的代码:

服务:

import {Injectable} from "@angular/core";
import {Gym} from "../objects/gym";
import {BaseService} from "./base.service";
import {Http, Response} from "@angular/http";
import {HttpConstants} from "../utility/http.constants";

@Injectable()
export class GymService extends BaseService {

   private gyms: Gym[] = [];

   constructor(protected http: Http, protected httpConstants: HttpConstants) {
      super(http, httpConstants);
      this.getAllGymsFromBackEnd();
   }

   getAllGymsFromBackEnd() {
      return super.get(this.httpConstants.gymsUrl).subscribe(
         (data: Response) => {
            for (let gymObject of data['gyms']) {
               this.gyms.push(<Gym>gymObject);
            }
         }
      );
   }

   getGyms() {
      return this.gyms;
   }

   getGym(id: number) {
      return this.gyms.find(
         gym => gym.id === id
      )
   }
}

组件:

import {Component, OnDestroy, AfterViewInit, OnInit} from "@angular/core";
import {ActivatedRoute} from "@angular/router";
import {Subscription} from "rxjs";
import {Gym} from "../../objects/gym";
import {GymService} from "../../services/gym.service";
declare var $:any;

@Component({
   selector: 'app-gym',
   templateUrl: './gym.component.html',
   styleUrls: ['./gym.component.css']
})
export class GymComponent implements OnInit, OnDestroy, AfterViewInit {

   private subscription: Subscription;
   private gym: Gym;

   constructor(private activatedRoute: ActivatedRoute,
            private gymService: GymService
   ) {}

   ngOnInit(): void {
      this.subscription = this.activatedRoute.params.subscribe(
         (param: any) => {
            this.gym = this.gymService.getGym(parseInt(param['id']));
         }
      );
   }

   ngAfterViewInit(): void {
      $( document ).ready(function() {
         $('.carousel').carousel();
      });
   }

   ngOnDestroy(): void {
      this.subscription.unsubscribe();
   }
}

【问题讨论】:

  • 您的服务应该公开一个事物可以订阅的可观察对象。例如,您可以使用ReplaySubject 作为缓存。使getGyms 返回Observable&lt;Gym[]&gt;。
  • 感谢您的回复,我按照您的建议进行了更改。你能看看我做对了吗?我也不知道如何实现 getGym(id) 函数并在组件中使用它,你能帮忙吗?
  • 在吸引到答案后不要更改问题。如果你想知道你是否做对了,那就去测试吧!
  • 是的,我测试了描述中的代码并且它可以工作(除了 getGym(id)),我只是想知道实现是否可以更简单/更好。
  • 如果你有你认为可以改进的工作代码,一旦你完成了所有的实现,请参阅Code Review。

标签: javascript ajax angular typescript


【解决方案1】:

您也可以使用Resolver。在这里查看https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html 或使用 Observable。所以private gym: Gym; 会变成private gym$:Observable&lt;Gym&gt;;,在你的模板中,使用async 管道来获取数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2018-01-02
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多