【问题标题】:Getting a data from a service which is populate through a service call in angular 2从通过角度 2 中的服务调用填充的服务获取数据
【发布时间】:2017-10-11 01:30:39
【问题描述】:

我有一个作为 UserService 的服务,它从它的构造函数中获取数据,然后它通过一个承诺填充它的 _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,这就是我尝试的方式:

export class WorkflowDisplayComponent implements OnInit {
  userData: GrcUser;

  constructor(private _userService: UserService,) {


  }
  ngOnInit(): void {
   this.userData = this._userService.userData;
  }
}

现在我明白为什么这不起作用了,直到承诺在用户服务中返回 _userData。我在 Observable 上阅读了一些内容,但我不太确定是否要使用它们以及在这种情况下如何准确地使用它们。

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

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

【问题讨论】:

    标签: angular angular-observable


    【解决方案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 调用并将其缓存在服务中,所有后续调用都将从服务的存储变量中提供。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      相关资源
      最近更新 更多