我正在寻找一种终止异步路由解析的方法。
该方案是用户单击获取组件所需数据的链接,同时解析用户点击或点击其他链接。然后我想取消当前的解决方案并开始新的路由。
我无法通过侦听这些更改来拦截路由,因为当现有路由(仍处于解决阶段)正在处理时,没有路由事件订阅触发。
例如,我的路由器可能如下所示:
const appRoutes: Routes = [
{
path: 'resolvableRoute',
component: ResolvableRouteComponent,
resolve: {
data: RouteResolver
}
}];
解析器:
@Injectable()
export class RouteResolver implements Resolve<any> {
constructor(private http: HttpClient) {}
public resolve(router: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
return this.http.get('api/path/for/data');
}
}
直到http呼叫以任何方式返回,路由器或多或少地卡住了。
我有一个很好的加载器,在路由转换时启动,我不希望显示新组件,直到我有该组件所需的数据,但我需要能够终止请求。 / p>
例如,如果我没有使用解析器,则用户可以在组件获取数据时离开组件(例如在init上),因为我可以随后破坏组件并终止http请求。以这种方式执行组件的缺点是,我在处理提取数据时必须显示空白页面或不完整的页面。
答案 0 :(得分:0)
我现在要发布我的解决方案作为答案,因为这项工作做了我需要它,也许它也会帮助其他人。
这个解决方案的缺点是我需要路由器的包装器,我宁愿不需要它。
理想情况下,我可能刚刚创建了对路由器导航队列的订阅,但所有这些方法/变量在角度路由器中都是私有的,因此我无法访问它们。
相反,我创建了一个RouterService,它允许我在新的导航事件触发时触发事件:
@Injectable()
export class RouterService {
protected navigateListener = new EventEmitter<any>();
constructor(private router: Router) {}
public subscribe(generatorOrNext?: any, error?: any, complete?: any) {
return this.navigateListener.subscribe(generatorOrNext, error, complete);
}
public navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
this.navigateListener.next();
return this.router.navigate(commands, extras);
}
public navigateByUrl(url: string | UrlTree, extras?: NavigationExtras): Promise<boolean> {
this.navigateListener.next();
return this.router.navigateByUrl(url, extras);
}
}
然后在我的Resolve中创建了一个observable(通常想要返回http请求),但是也在侦听RouterService上的事件更改。如果发出了路由导航,那么我终止了http请求,让承诺知道它可以完成......
public resolve(router: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
return new Promise((resolve: any, reject: any) => {
const subscription = this.http.get('/path/to/some/url').subscribe((data) => {
resolve(data)
}, (error) => {
reject({
ngNavigationCancelingError: true
});
});
this.router.subscribe(change => {
subscription.unsubscribe();
reject({
ngNavigationCancelingError: true
});
});
});
}
答案 1 :(得分:0)
这对我来说很好(角度7)
解析器
public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
return new Observable((observer) => {
this.http.get().pipe(
tap(data => {
if (data !== undefined) {
observer.next(data);
}
else {
observer.unsubscribe();
}
observer.complete();
})
).subscribe();
});
}
组件
public ngOnInit() {
this.route.data.subscribe((parameters: { data: { objs: MyObjs[] } }) => {
if (parameters.data) {
this.dataSource = new MatTableDataSource(parameters.data.objs);
this.dataSource.sort = this.sort;
}
});
}
服务
public get(): Observable<any> {
return this.http.get<any>(`${environment.apiUrl}/api/get`).pipe(
map((response: ApiResponse) => {
return response.data
}),
catchError(err => of(undefined))
);
}