Angular2 在服务和组件之间同步

Angular2 sync up between service and Component

我有一个 "HomeComponent",它在 UI 中显示用户名。

使用服务从 json 文件中读取用户名。

我在 AppComponent(HomeComponent 的父组件)中提供了服务并在 HomeComponent 中重用

AppComponent.html

<router-outlet></router-outlet>

AppComponent.ts

export class AppComponent {
constructor(private userService: UserService) {
    this.userService.fetchUserDetails();
}
}

UserService.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { User } from '../models/user';

import 'rxjs/add/operator/first';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class AppStateManagerService {
   private userDetails: User;

  private initializeUser(data) {
    this.userDetails = new User();
    this.userDetails.name = data.username;
    this.userDetails.id = data.userid;
   }
constructor(private http: HttpClient) {}

async fetchDeviceDetails() {
    let response = await this.http
        .get('./app/config/user.json')
        .first()
        .toPromise();
    this.initializeUser(response);
    return this.userDetails;
}

getUserDetails() {
    return this.userDetails;
}

}

HomeComponent.html

<div>{{user && user.name}}</div>

HomeComponent.ts

export class HomeComponent {
    user: User;

    constructor(private userService: userService) {
        this.user = this.userService.getUserDetails();
    }
}

我这里遇到的问题是,HomeComponent首先被初始化,在JSON解析完成之前,也就是AppComponent中的fetchUserDetails()完成之前,HomeComponent中的getUserDetails()被调用并且user.name 在 HTML 中为空,然后才填充到服务中。

有办法同步吗?不使用 Observable?

fetchDeviceDetails() 是异步的,所以我希望你能同意我的看法,getUserDetails() 将立即 return 未定义。简单的东西吧?

那么如何解决这个问题:您需要让 HomeComponent 知道数据可用。我们使用 Observables 来做到这一点。一个例子是:

fetchDeviceDetails(): Observable<any> {
  return new Observable(observer => {
    this.http.get(whatever).subscribe(
      res => {
        this.initializeUser(res);
        observer.next(res);
      }
    );    
  });
}

现在您可以订阅此活动了:

constructor(private userService: userService) {
  this.userService.fetchDeviceDetails().subscribe(
    res => this.user = res
  );
}

另一种选择是像这样使用 getter:

export class HomeComponent {
    get user(): User {
       return this.userService.getUserDetails();
    }

    constructor(private userService: userService) {  }
}

这利用 Angular 的更改检测来确保用户数据一可用就在 UI 中设置。