简体   繁体   English

Angular如何订阅界面更改?

[英]Angular how to subscribe to interface changes?

I am trying to subscribe to my interface and watch for changes, but I have errors. 我正在尝试订阅我的界面并观察更改,但是我遇到了错误。

  1. Getting data from api and asigning it to this.candidateProfile : 从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 : 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 : Component.ts:

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

error : 错误:

this.auth.candidateProfile.subscribe is not a function this.auth.candidateProfile.subscribe不是函数

When you subscribe to an observable, you subscribe to its value, which is not an observable. 当您订阅一个可观察对象时,您就订阅了它的值,这不是一个可观察对象。 When you are doing: 在执行操作时:

this.candidateProfile = data;

You are essentially storing in candidateProfile the value that you got from the observable. 您实际上是将您从可观察值中获得的值存储在候选人配置文件中。 Of course this data does not have the function 'subscribe' anymore since it's not an observable. 当然,此数据不再具有“订阅”功能,因为它不是可观察的。

You should store in 'this.candidateProfile' the observable itself, not the value that you get from it. 您应该将“ observable”本身存储在“ this.candidateProfile”中,而不是从中获取的值。 Like so: 像这样:

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

Hope that I helped you, have a nice day! 希望我对您有所帮助,祝您有美好的一天!

That is not always the best way to do things. 那并不总是最好的做事方式。 You should not return the observable on your service file. 您不应在服务文件上返回观察值。 The standard practice is to return the observable on your component itself. 标准做法是在组件本身上返回可观察对象。

In terms of error handling, you can either do it on your service, or on your component. 在错误处理方面,您可以在服务上或在组件上进行操作。 For the example I am providing below, I will be handling the errors on the component. 对于下面提供的示例,我将处理组件上的错误。

On your service, you will need to add the return statement: 在您的服务上,您将需要添加return语句:

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

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

On your component.ts, you subscribe to it to return the observable value: 在您的component.ts上,您预订它以返回可观察的值:

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

modify your auth service like following 修改您的身份验证服务,如下所示

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();
    }
}

then you can use as following : 那么您可以使用以下方法:

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

Explication 解释

Goal is to have internal observable on this service which will broadcast your current candidate profile. 目标是使该服务具有内部可观察性,并将广播您当前的候选人资料。

Anywhere on your application you can subscribe to it and get latest fetched profil without trigger again the getProfile method (and ajax request under the hood). 您可以在应用程序中的任何位置订阅它,并获取最新的访存配置文件,而无需再次触发getProfile方法(以及getProfile ajax请求)。

to make it more easy to consume out of AuthService i have create magic getter to abstract it. 为了更轻松地从AuthService我创建了一个神奇的getter来对其进行抽象。

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

it take your BehaviorSubject and turn it to simple Observable . 它把你的BehaviorSubject变成简单的Observable Otherwise you allow AuthService consumer to next on your Observable , and it not what is expected. 否则,您将允许AuthService使用者在您的Observable上显示下一个,这不是预期的。

the only one way to broadcast new CandidateProfile should be here : 广播新CandidateProfile的唯一方法应该是在这里:

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

I also recommand you to change your getProfile like following 我也建议您像下面那样更改您的getProfile

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

    return this.candidateProfile$;
}

Like this you can consume your class as following : 这样,您可以按以下方式使用您的课程:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM