从角度为2的服务调用填充的服务获取数据

时间:2017-10-10 16:55:43

标签: angular angular-observable

我有一个UserService服务,它获取有关其构造函数的数据,然后通过promise填充_userData的属性,这是服务:

std::vector <sf::VideoMode> *screenResolution = new std::vector<sf::VideoMode>;

*screenResolution = sf::VideoMode::getFullscreenModes();

for (std::size_t i = 0; i < screenResolution->size(); ++i)
{
    std::cout << screenResolution[i]->width << ":" << screenResolution[i]->height <<std::endl;
}

现在,我想在另一个组件中获取userData,这就是我尝试的方式:

    @Injectable()
    export class UserService {
      private _userData: GrcUser = null;


      constructor(private logger: LogService, private http: Http, private noteService: NotificationsService) {
        logger.trace('UserService Created');
        this.getUserInfo() ;
    }
      public getUserInfo() {
        let userID: string = this.getCookieValue('grcUserId');
        let headers = new Headers({ 'X-West-session-token': this.getCookieValue("grcSessionToken") });
        if (userID) {
          this.http.get(AppConstants.USER_URL + "userInfo/" + userID, { headers: headers })
            .map((res: Response) => res.json())
            .toPromise()
            .then((data: GrcUser) => {
             this._userData = data;
            if (!data) {
            this.noteService.add(new Note('danger', 'Failed to load user 
           details'));
              }
            })
            .catch((err: any) => {
              this.logger.error(err);
              this.noteService.add(new Note('danger', 'Error while getting user details'));
              Promise.resolve();
            });
        } else {
          this.noteService.add(new Note('danger', 'You are not logged in. Please log in and try again'));
    }
  }

现在我理解为什么这不起作用,我不会在承诺在用户服务中返回_userData之前做出决定。我在Observable上阅读了一些内容,但我不确定是否要使用它们以及我在这种情况下如何使用它们。

如果我想使用Observables,我似乎必须在userService中更改我的getUserInfo函数

有没有更好的方法可以做到这一点,而无需过多地重构我的代码

1 个答案:

答案 0 :(得分:1)

您不应该将http observable转换为toPromise()。在这种情况下,您可以多播您的http observable并将其缓存在您的服务中。

    @Injectable()
    export class UserService {
      private _userData: GrcUser = null;
      private httpObservable: Observable;

      constructor(private logger: LogService, private http: Http, private noteService: NotificationsService) {
        logger.trace('UserService Created');
        this.getUserInfo() ;
    }
      public getUserInfo() {
        let userID: string = this.getCookieValue('grcUserId');
        let headers = new Headers({ 'X-West-session-token': this.getCookieValue("grcSessionToken") });
        if (userID) {
         if(this.httpObservable){
             return this.httpObservable;
         } else if(this._userData){
            return Observable.of(this._userData);
         } else {
         this.httpObservable = this.http.get(AppConstants.USER_URL + "userInfo/" + userID, { headers: headers })
            .map((res: Response) => res.json())
            .do((data: GrcUser) => {
             this._userData = data;
            if (!data) {
            this.noteService.add(new Note('danger', 'Failed to load user 
           details'));
              }

            }).catch( (err: any) => {
              this.logger.error(err);
              this.noteService.add(new Note('danger', 'Error while getting user details'));
              return Observable.of(false);
            }).share();
            return this.httpObservable;
           }
        } else {
          this.noteService.add(new Note('danger', 'You are not logged in. Please log in and try again'));
          return return Observable.of(false);
    }
  }

在代码中,请注意.share()方法。这将多播您的observable。 在您的任何其他组件中:

export class WorkflowDisplayComponent implements OnInit {
  userData: GrcUser;

  constructor(private _userService: UserService,) {
  }
  ngOnInit(): void {
   this._userService.getUserInfo()
                   .subscribe((userData: any) => {
                       if(userData !== false) {
                          this.userData = userData;
                       }
                    });
  }
}

这样,您只需进行一次http呼叫并在服务中缓存它,所有后续呼叫都将从服务的存储变量中提供。