Angular 2,Observables - 从subscribe返回一些数据

时间:2016-10-14 07:15:26

标签: angular typescript rxjs

我有一个登录组件和一个简单的方法:

login(event) {       
    event.preventDefault();
    this.authService.login(this.user);       
}

这是我的AuthService

export class AuthService {
    constructor(private jsonApiService:JsonApiService) {
    }

    isLoggedIn: boolean = false;

    login(user:User): any {
        this.jsonApiService.post('/token', user)
            .subscribe(
                resp => {
                   check if success,
                   store token to localstorage,
                   set isLoggedIn = true
                   * return new object with data about success/error


                },
                err => {    
                    handle error
                    * return new object with data about success/error
                });
    }

    logout(): void {
        this.isLoggedIn = false;
    }
}

此代码工作正常。我得到了回应,但我想知道如何将一些数据从服务返回到组件。我不想移动订阅组件,因为我相信处理必须在AuthService中。

4 个答案:

答案 0 :(得分:5)

由于http请求运行async,你不能从lambda内部返回一些东西,但你可以传递一个这样的回调(这基本上就像订阅):

login(user: User, onSuccess: (data) => void, onError: (data) => void = null): any {
    this.jsonApiService.post('/token', user)
        .subscribe(
            resp => {
               check if success,
               store token to localstorage,
               set isLoggedIn = true

               onSuccess(/*somedata*/);
            },
            err => {    
               handle error

               if (onError)
                   onError(/*somedata*/);
            });
}

然后在你的组件中:

login(event) {       
    event.preventDefault();
    this.authService.login(this.user, (data) => {
        // do something here with the data
    });    

    // or optionally with onError callback
    this.authService.login(this.user, (data) => {
        // do something here with the data
    },
    (errData) => {
        // do something with the error
    });      
}

答案 1 :(得分:1)

您可以执行类似这样的操作,返回一个新的observable,它连接到函数范围内的另一个观察者。

这样你的调用组件就可以订阅返回的Observable,例如使用异步管道,并且只要调用observer.next就会收到通知

我没有对此进行测试,因此可能需要进行一些修改,但我希望它能为您指明方向!

login(user:User): any {
        return new Observable((observer: any) => {
            this.jsonApiService.post('/token', user)
                .subscribe(
                resp => {
                    check if success,
                    store token to localstorage,
                    set isLoggedIn = true
                    obs.next(someResponse);
                    obs.complete();
                },
                err => {
                    handle error
                    obs.next(someResponse);
                    obs.complete();
                });
        }
    }

答案 2 :(得分:0)

如果您希望observable的订阅包含在AuthService中,并希望返回一个异步操作的结果,那么听起来就像是一个承诺。

您可以使用RxJS toPromise运算符执行此操作。它会为您管理subscribe(和unsubscribe):

login(user: User): Promise<any> {

    return this.jsonApiService
        .post('/token', user)
        .toPromise()
        .then((result) => {
            // check if success,
            // store token to localstorage,
            // set isLoggedIn = true
            // return new object with data about success/error          
        })
        .catch((error) => {
            // handle error
            // return new object with data about success/error          
        });
}

答案 3 :(得分:-1)

可能你可以做以下事情:

// AuthService

export class AuthService {
    constructor(private jsonApiService:JsonApiService) {
    }

    isLoggedIn: boolean = false;

    login(user:User): any {
        this.jsonApiService.post('/token', user)
            .map(
                resp => {
                   /**
                    * check if success,
                    * store token to localstorage
                    */
                    set isLoggedIn = true
                   //return new object with data about success/error
                   return resp.json(); // return response or your new created object

                });
    }

    logout(): void {
        this.isLoggedIn = false;
    }
}

//组件

login(event) {       
  event.preventDefault();
  this.authService.login(this.user).subscribe(res => {
    console.log(res);
  },err => {    
    handle error
    * return new object with data about success/error
  });       
}