我想:
如果我是通过浏览器网址框直接完成的,那么效果很好但是当我使用router.navigate(["/users", "userName"]);
时,它可以减慢速度。
ngOnInit(): void {
this.sub = this._route.params.subscribe(
params => {
this.userName = params['name'];
});
this._usersService.getUser(this.userName)
.subscribe(user => this.user = user,
error => this.errorMessage = <any>error);
}
这是UserComponent中的代码。
this._userService
有时会在this.sub
之前完成。
如何解决?
答案 0 :(得分:0)
您可以使用switchMap
从params
observable切换到getUser()
提供的可观察量。
// an observable of users
this.user$ = this._route.params
// switch to the observable provided by getUser() which queries the resource
.switchMap(params => this.getUser(params['name']))
// log error
.catch(error => {
console.log('Error occurred - ' + error.message);
// rethrow
return Observable.throw(error);
})
// share a single subscription among the subscribers so that getUser() will not be called for every subscriber
.share();
然后,您可以将此可观察对象投影到另一个对您的案例有用的对象,例如:
// an observable of user details to be displayed on template
this.userInfo$ = this.user$.map(user => user.username + ' - ' + user.date.toISOString());
最后,您可以在模板中使用observable:
The user is: {{ userInfo$ | async }}
请参阅此PLUNKER
中的工作示例 UserComponent
的完整代码:
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/delay';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/observable/of';
@Component({
selector: 'app-user',
template: `The user is: {{ userInfo$ | async }}`
})
export class UserComponent implements OnInit {
public user$: Observable<User>;
public userInfo$: Observable<string>;
constructor(private _route: ActivatedRoute) {
}
ngOnInit() {
// an observable of users
this.user$ = this._route.params
// switch to the observable provided by getUser() which queries the resource
.switchMap(params => this.getUser(params['name']))
// log error
.catch(error => {
console.log('Error occurred - ' + error.message);
// rethrow
return Observable.throw(error);
})
// share a single subscription among the subscribers so that getUser() will not be called for every subscriber
.share();
// an observable of user details to be displayed on template
this.userInfo$ = this.user$.map(user => user.username + ' - ' + user.date.toISOString());
}
private getUser(username: string): Observable<User> {
// occasionally create error
if (username === 'error') {
return Observable.throw(new Error('Occasional error'));
}
// create a user after 300 ms
return Observable.of({username: username, date: new Date()}).delay(300);
}
}
export interface User {
username: string;
date: Date;
}