Angular如何订阅界面更改?

时间:2019-05-02 09:45:49

标签: angular typescript rxjs

我正在尝试订阅我的界面并观察更改,但是我遇到了错误。

  1. 从api获取数据并将其分配给this.candidateProfile:

     export interface CandidateProfile {
     about: string,
     c_id: {},
     certificates_training: [],
     city: string,
     country: string,
     currency: string,
     email: string,
     expectedpayhourly: boolean,
     expectedpayhourlyend: number,
     expectedpayhourlystart: number,
     expectedpaymonthly: {},
     expectedpaymonthlyend: number,
     expectedpaymonthlystart: number,
     experience: [],
     firstname: string,
     hobbies: {},
     jobskills: [],
     langugaes: {},
     lastname: string,
     personalskills: [],
     photo: string,
     remotework: boolean,
     role: string,
     studies: {},
     willingtorelocate: {},
     willingtorelocatecity: {},
     worktype: string
      }
    

Auth.service.ts:

candidateProfile: Observable<CandidateProfile>;

getProfile(id, token) {
const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  })
};

this.http.get(`users/${id}`, httpOptions).subscribe(data => {
  this.candidateProfile = data;
},
  (error) => { console.log(error) },
  () => {
    console.log('got profile', this.candidateProfile);
  })

 }

Component.ts:

this.auth.candidateProfile.subscribe( data => {
console.log(data)
})

错误:

this.auth.candidateProfile.subscribe不是函数

3 个答案:

答案 0 :(得分:1)

当您订阅一个可观察对象时,您将订阅它的值,这不是一个可观察对象。做的时候:

this.candidateProfile = data;

您实质上是在将您从可观察值中获得的值存储在候选人配置文件中。当然,由于该数据不可观察,因此不再具有“订阅”功能。

您应该将“ observable”本身存储在“ this.candidateProfile”中,而不是从中获取的值。像这样:

this.candidateProfile = this.http.get(`users/${id}`, httpOptions);

希望我对您有所帮助,祝您愉快!

答案 1 :(得分:1)

这并不总是最好的方法。您不应在服务文件上返回观察值。标准做法是在组件本身上返回可观察对象。

在错误处理方面,您可以在服务上或组件上进行操作。对于下面提供的示例,我将处理组件上的错误。

在您的服务中,您将需要添加return语句:

getProfile(id, token) {
  const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    })
  };

  return this.http.get(`users/${id}`, httpOptions);
}

在您的component.ts上,您订阅它以返回可观察的值:

this.auth.candidateProfile.subscribe( data => {
  console.log(data)
}, error => {
  // handle error
});

答案 2 :(得分:1)

像下面一样修改您的身份验证服务

export class AuthService {
    private _candidateProfile$: BehaviorSubject<CandidateProfile> = new BehaviorSubject(null);

    getProfile(id, token): void {
        const httpOptions = {
            headers: new HttpHeaders({
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            })
        };

        this.http.get(`users/${id}`, httpOptions).subscribe(data => {
                this._candidateProfile$.next(data);
            },
            (error) => { console.log(error) },
            () => {
                console.log('got profile', data);
            })
    }

    get candidateProfile$(): Observable<CandidateProfile> {
      return this._candidateProfile$.asObservable();
    }
}

然后您可以使用以下内容:

this.auth.candidateProfile$.subscribe( data => {
console.log(data)
})

说明

目标是在此服务上具有内部可观察性,它将广播您当前的候选人资料。

在应用程序的任何位置,您都可以订阅它并获取最新获取的配置文件,而无需再次触发getProfile方法(以及后台的ajax请求)。

为了更容易使用AuthService,我创建了一个抽象的吸气剂。

get candidateProfile$(): Observable<CandidateProfile> {
  return this._candidateProfile$.asObservable();
}

将您的BehaviorSubject转换为简单的Observable。否则,您将允许AuthService消费者继续使用Observable,这不是预期的结果。

唯一的广播新CandidateProfile的方法应该在这里:

 this.http.get(`users/${id}`, httpOptions).subscribe(data => {
      this._candidateProfile$.next(data);
 });

我也建议您按照以下说明更改您的getProfile

getProfile(id, token): Observable<CandidateProfile> {
    // [...]
    this.http.get(`users/${id}`, httpOptions).subscribe(data => {
           this._candidateProfile$.next(data);
        },
        // [...]
    );

    return this.candidateProfile$;
}

像这样,您可以按以下方式使用您的课程:

// Fetch new profile.
this.auth.getProfile(id, token).subscribe();
// Fetch last requested profile.
this.auth.candidateProfile$.subscribe();