通常我会提供一个HttpService
自己而不是Http
直接使用。get()
因此,根据您的要求,我可以在发送任何真正的 HTTP 请求之前提供自己的方法来链接身份验证。
这是服务:
@Injectable()
class HttpService {
constructor(private http: Http, private auth: Authentication) {}
public get(url: string): Observable<Response> {
return this.auth.authenticate().flatMap(authenticated => {
if (authenticated) {
return this.http.get(url);
}
else {
return Observable.throw('Unable to re-authenticate');
}
});
}
}
这是调用服务的组件:
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>
<button (click)="doSomething()">Do Something</button>
<div [hidden]="!auth.showModal">
<p>Do you confirm to log in?</p>
<button (click)="yes()">Yes</button><button (click)="no()">No</button>
</div>
`,
})
export class AppComponent {
name = 'Angular';
constructor(private httpSvc: HttpService, public auth: Authentication) {}
ngOnInit() {
}
doSomething() {
let a = this.httpSvc.get('hello.json').subscribe(() => {
alert('Data retrieved!');
}, err => {
alert(err);
});
}
yes() {
this.auth.confirm.emit(true);
}
no() {
this.auth.confirm.emit(false);
}
}
通过链接可观察对象,Authentication
服务确定是否中断正常流程以显示模态(虽然目前仅与 App 组件一起存在,但它当然可以单独实现)。一旦从对话中收到肯定的回答,服务就可以恢复流程。
class Authentication {
public needsAuthentication = true;
public showModal = false;
public confirm = new EventEmitter<boolean>();
public authenticate(): Observable<boolean> {
// do something to make sure authentication token works correctly
if (this.needsAuthentication) {
this.showModal = true;
return Observable.create(observer => {
this.confirm.subscribe(r => {
this.showModal = false;
this.needsAuthentication = !r;
observer.next(r);
observer.complete();
});
});
}
else {
return Observable.of(true);
}
}
}
我在这里有一个完整的例子。
http://plnkr.co/edit/C129guNJvri5hbGZGsHp?open=app%2Fapp.component.ts&p=preview