Angular2:如何正确地在服务和组件内部订阅可观察的Http.post? [英] Angular2: How to subscribe to Http.post observable inside a service and a component properly?

查看:123
本文介绍了Angular2:如何正确地在服务和组件内部订阅可观察的Http.post?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于JWT身份验证,我发出了一个发布请求,以使用现在与Observables一起使用的新的 Http 模块来获取令牌.

For a JWT authentification, I make a post request to get the token using the new Http module working with Observables now.

我有一个简单的 Login 组件,显示了以下形式:

I have a simple Login component showing the form:

@Component({
selector: 'my-login',
    template: `<form (submit)="submitForm($event)">
                <input [(ngModel)]="cred.username" type="text" required autofocus>
                <input [(ngModel)]="cred.password" type="password" required>
                <button type="submit">Connexion</button>
            </form>`
})
export class LoginComponent {
    private cred: CredentialsModel = new CredentialsModel();

    constructor(public auth: Auth) {}

    submitForm(e: MouseEvent) {
        e.preventDefault();
        this.auth.authentificate(this.cred);
    }
}

我有一个发出请求的 Auth 服务:

I have a Auth service making the request:

@Injectable()
export class Auth {
    constructor(public http: Http) {}

    public authentificate(credentials: CredentialsModel) {
        const headers = new Headers();
        headers.append('Content-Type', 'application/json');

        this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
            .map(res => res.json())
            .subscribe(
                data => this._saveJwt(data.id_token),
                err => console.log(err)
            );
    }
}

工作正常,但现在我想在组件内部显示错误消息,因此我需要在2个地方进行订阅( Auth 用于管理成功,而 Login 用于管理错误).

Works well but now I want to display error messages inside my component so I need to subscribe in 2 places (Auth for managing success and Login for managing error).

我使用 share 运算符实现了它:

I achieved it using share operator:

public authentificate(credentials: CredentialsModel) : Observable<Response> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/json');

    const auth$ = this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
                            .map(res => res.json()).share();

    auth$.subscribe(data => this._saveJwt(data.id_token), () => {});

    return auth$;
}

在组件内部:

submitForm(e: MouseEvent) {
    e.preventDefault();
    this.auth.authentificate(this.cred).subscribe(() => {}, (err) => {
        console.log('ERROR component', err);
    });
}

它可以工作,但是我觉得做错了.我只是用angular1和 promises 转换了我们的处理方式,您看到实现它的更好方法了吗?

It works but I feel doing it wrong.. I just transpose the way we did it with angular1 and promises, do you see better way to achieve it?

推荐答案

当可以使用此方法时,为什么要在 sharedService 中订阅!

Why would you subscribe to in sharedService, when this approach can be used !

@Injectable()
export class Auth {
    constructor(public http: Http) {}

    public authentificate(credentials: CredentialsModel) {
        const headers = new Headers();
        headers.append('Content-Type', 'application/json');

            return  this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})      //added return
            .map(res => res.json());
            //.subscribe(
            //    data => this._saveJwt(data.id_token),
            //    err => console.log(err)
            //);
    }
}


@Component({
selector: 'my-login',
    template: `<form (submit)="submitForm($event)">
                <input [(ngModel)]="cred.username" type="text" required autofocus>
                <input [(ngModel)]="cred.password" type="password" required>
                <button type="submit">Connexion</button>
            </form>`
})
export class LoginComponent {
    private cred: CredentialsModel = new CredentialsModel();

    constructor(public auth: Auth) {}

    submitForm(e: MouseEvent) {
        e.preventDefault();
        this.auth.authentificate(this.cred).subscribe(
               (data) => {this.auth._saveJwt(data.id_token)},  //changed
               (err)=>console.log(err),
               ()=>console.log("Done")
            );
    }
}


编辑
如果您要订阅 sharedService component ,仍然可以肯定地使用这种方法. 但是我不建议这样做 ,而是在我对修改的部分看似完美之前.


Edit
still if you want to subscribe in sharedService and component you can surely go with this approach. But I'd not recommend this rather before edited section seems perfect to me.

我无法使用您的代码对其进行测试.但请查看我的此处的示例(已测试).点击 myFriends选项卡,检查浏览器控制台和用户界面.浏览器控制台显示 sharedService &的订阅结果UI显示 component 的订阅结果.

I can't test it with your code. but look at my example here(tested). click on myFriends tab,check browser console and UI. browser console shows subscription result of sharedService & UI shows subscription result of component.

  @Injectable()
  export class Auth {
    constructor(public http: Http) {}

    public authentificate(credentials: CredentialsModel) {
        const headers = new Headers();
        headers.append('Content-Type', 'application/json');

           var sub =  this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})      //added return
            .map(res => res.json());

           sub.subscribe(
                data => this._saveJwt(data.id_token),
                err => console.log(err)
               );

           return sub;
    }
}


export class LoginComponent {
    private cred: CredentialsModel = new CredentialsModel();

    constructor(public auth: Auth) {}

    submitForm(e: MouseEvent) {
        e.preventDefault();
        this.auth.authentificate(this.cred).subscribe(
               (data) => {this.auth._saveJwt(data.id_token)},  //not necessary to call _saveJwt from here now.
               (err)=>console.log(err),
               ()=>console.log("Done")
            );
    }
}

这篇关于Angular2:如何正确地在服务和组件内部订阅可观察的Http.post?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆