在 Angular 2 中取消解析器的路由导航
Cancel Route Navigation from Resolver in Angular 2
我需要在承诺拒绝时取消路由并留在当前页面而不重定向到 default/error 页面,
我尝试了不同的方法来拒绝承诺,但最终解析了路由或重定向到默认路由。
@Injectable()
export class ModelResolver implements Resolve<MyModel> {
constructor(private router: Router) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
let params: any = route.params;
let model: MyModel= new MyModel();
return model.init().then((obj: MyModel) => {
return obj;
}).catch((err: any) => {
Promise.reject({message: err , ngNavigationCancelingError: true});
});
}
}
reject({message: err , ngNavigationCancelingError: true});
// 重定向到我的默认路由
return Observable.throw({message: err , ngNavigationCancelingError: true});
// 重定向到当前路由而不取消
resolve(null); or return Observable.empty()
// 重定向到当前路由而不取消
使用此变通方法拒绝并停留在路由解析器的同一页面上。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
return new Promise((resolve, reject) => {
return model.init().then((obj: any) => {
resolve(obj);
}).catch((err: any) => {
this.router.navigateByUrl(this.location.path());
resolve(false);
});
});
}
为了从解析器取消路由,您可以使用可观察的而不是承诺并调用:observer.complete()而不调用:observer.next()
例如:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
return new Observable((observer) => {
let somePromiseOrObservableToGetDate=?????;
somePromiseOrObservableToGetDate.then(data => {
if (data) {
observer.next(1);
}
observer.complete();
})
.catch((err: any) => {
observer.complete();
});
});
}
在你的例子中:
let model: MyModel = new MyModel();
return new Observable((observer) => {
model.init().then((obj: any) => {
observer.next(obj);
observer.complete();
})
.catch((err: any) => {
observer.complete();
});
});
取消导航的一种方法是在不返回任何数据的情况下完成 Observable
。我找不到关于此行为的文档,但似乎有效。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
let params: any = route.params;
let model: MyModel= new MyModel();
return Observable.fromPromise(model.init()).pipe(
catchError((err: any) => Observable.empty());
}
使用 Angular 6 我可以阻止导航发生的唯一方法是从解析器流中抛出一个未处理的错误。最简单的测试方法:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
// throwError imported from 'rxjs'.
return throwError('some error object');
}
如果您 return 一个永远不会完成的流(即来自 'rxjs'
的 NEVER
),那么导航也不会发生,但是路由器会继续等待流到完成或错误(永远不会发生)意味着所有路由操作将停止工作。
2021 年更新:
这在解析器文档中找不到,但 Angular 10 upgrade guide 提到:
Any resolver which returns EMPTY will cancel navigation. If you want
to allow navigation to continue, you will need to update the resolvers
to emit some value, (i.e. defaultIfEmpty(...), of(...), etc).
用 EMPTY
试了一下,现在确实有效。不再需要抛出错误来取消导航。
您可以在 resolve 方法中 return EMPTY observable。下面是取消导航的 resolve 方法示例
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<T> | Observable<T> {
return EMPTY;
}
注意:EMPTY
是从 rxjs
导入的
我需要在承诺拒绝时取消路由并留在当前页面而不重定向到 default/error 页面, 我尝试了不同的方法来拒绝承诺,但最终解析了路由或重定向到默认路由。
@Injectable()
export class ModelResolver implements Resolve<MyModel> {
constructor(private router: Router) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
let params: any = route.params;
let model: MyModel= new MyModel();
return model.init().then((obj: MyModel) => {
return obj;
}).catch((err: any) => {
Promise.reject({message: err , ngNavigationCancelingError: true});
});
}
}
reject({message: err , ngNavigationCancelingError: true});
// 重定向到我的默认路由
return Observable.throw({message: err , ngNavigationCancelingError: true});
// 重定向到当前路由而不取消
resolve(null); or return Observable.empty()
// 重定向到当前路由而不取消
使用此变通方法拒绝并停留在路由解析器的同一页面上。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
return new Promise((resolve, reject) => {
return model.init().then((obj: any) => {
resolve(obj);
}).catch((err: any) => {
this.router.navigateByUrl(this.location.path());
resolve(false);
});
});
}
为了从解析器取消路由,您可以使用可观察的而不是承诺并调用:observer.complete()而不调用:observer.next()
例如:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
return new Observable((observer) => {
let somePromiseOrObservableToGetDate=?????;
somePromiseOrObservableToGetDate.then(data => {
if (data) {
observer.next(1);
}
observer.complete();
})
.catch((err: any) => {
observer.complete();
});
});
}
在你的例子中:
let model: MyModel = new MyModel();
return new Observable((observer) => {
model.init().then((obj: any) => {
observer.next(obj);
observer.complete();
})
.catch((err: any) => {
observer.complete();
});
});
取消导航的一种方法是在不返回任何数据的情况下完成 Observable
。我找不到关于此行为的文档,但似乎有效。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
let params: any = route.params;
let model: MyModel= new MyModel();
return Observable.fromPromise(model.init()).pipe(
catchError((err: any) => Observable.empty());
}
使用 Angular 6 我可以阻止导航发生的唯一方法是从解析器流中抛出一个未处理的错误。最简单的测试方法:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
// throwError imported from 'rxjs'.
return throwError('some error object');
}
如果您 return 一个永远不会完成的流(即来自 'rxjs'
的 NEVER
),那么导航也不会发生,但是路由器会继续等待流到完成或错误(永远不会发生)意味着所有路由操作将停止工作。
2021 年更新:
这在解析器文档中找不到,但 Angular 10 upgrade guide 提到:
Any resolver which returns EMPTY will cancel navigation. If you want to allow navigation to continue, you will need to update the resolvers to emit some value, (i.e. defaultIfEmpty(...), of(...), etc).
用 EMPTY
试了一下,现在确实有效。不再需要抛出错误来取消导航。
您可以在 resolve 方法中 return EMPTY observable。下面是取消导航的 resolve 方法示例
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<T> | Observable<T> {
return EMPTY;
}
注意:EMPTY
是从 rxjs