对于JWT身份验证,我现在使用新的Http模块使用Observables发出一个post请求来获取令牌.
@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服务提出请求:
@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用于管理错误).
我使用share运算符实现了它:
public authentificate(credentials: CredentialsModel) : Observable<Response> { const headers = new Headers(); headers.append('Content-Type','application/json'); const auth$= this.http.post(config.LOGIN_URL,{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转换我们的方式,你看到更好的方法实现它吗?
解决方法
当可以使用此方法时,为什么要在sharedService中订阅!
@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,{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和组件,您肯定可以采用这种方法.但是在编辑部分之前我不推荐这个,对我来说似乎很完美.
我无法用你的代码测试它.但是看看我的example here(tested).点击myFriends标签,查看浏览器控制台和用户界面.浏览器控制台显示sharedService&的订阅结果. UI显示组件的订阅结果.
@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,{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") ); } }