【问题标题】:Cancel Route Navigation from Resolver in Angular 2从Angular 2中的解析器取消路线导航
【发布时间】:2021-07-22 05:02:44
【问题描述】:

我需要取消承诺拒绝的路线并留在当前页面而不重定向到默认/错误页面, 我尝试了不同的方式来拒绝承诺,但最终解决了路由或重定向到默认路由。

@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() // 重定向到当前路由而不取消

【问题讨论】:

  • 我需要先解析数据,然后再决定是否导航。 stackoverflow.com/questions/42652708/…
  • 好的,我假设你将有一个服务调用来获取 Rote Render 中的数据,你不能从 CanDeactivate 调用相同的服务吗?理想情况下,您应该拥有 CanDeactivate 中的服务调用可能需要的所有参数?
  • CanDeactivate 可以在离开路线时使用,以检查/通知任何未保存的数据。 CanActivate 在数据解析之前执行,我可以将此调用移至 CanActivate,但它不会像 issue 中提到的那样保留数据

标签: typescript redirect angular2-routing


【解决方案1】:

为了从resolver取消路由,你可以使用observable代替promise并调用: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();
    });
});

【讨论】:

  • 这种行为在 Angular 6 中可能改变了吗?使用此代码仍然可以进行导航。
  • 与@AlexPeters 有同样的问题,上面的方法只是继续导航而不解析实际值。对此有何想法?
  • 这篇文章是关于路由守卫,而不是数据Resolve守卫。不幸的是,他们似乎没有在那里添加相同的功能。
【解决方案2】:

使用 Angular 6 阻止导航发生的唯一方法是从解析器流中抛出未处理的错误。最简单的测试方法:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // throwError imported from 'rxjs'.
    return throwError('some error object');
}

如果您返回一个永远不会完成的流(即来自'rxjs'NEVER),导航也不会发生,但路由器将继续等待流完成或错误(这永远不会发生) 意味着所有路由操作都将停止工作。

2021 年更新:

这在解析器文档中找不到,但 Angular 10 upgrade guide 提到:

任何返回 EMPTY 的解析器都会取消导航。如果你想 要允许导航继续,您需要更新解析器 发出一些值,(即 defaultIfEmpty(...)、of(...) 等)。

EMPTY 尝试过,现在确实有效。不再需要抛出错误来取消导航。

【讨论】:

    【解决方案3】:

    取消导航的一种方法是在不返回任何数据的情况下完成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());
    }
    

    【讨论】:

      【解决方案4】:

      您可以在 resolve 方法中返回 EMPTY observable。下面是一个取消导航的resolve方法示例

        resolve(
          route: ActivatedRouteSnapshot,
          state: RouterStateSnapshot
        ): Observable<T> | Observable<T> {
      
          return EMPTY;
          
        }
      

      注意:EMPTY 是从 rxjs 导入的

      【讨论】:

        【解决方案5】:

        使用此解决方法来拒绝并保持在路由解析器的同一页面上。

        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);
                    });
                });
        
            }
        

        【讨论】:

          猜你喜欢
          • 2016-06-28
          • 1970-01-01
          • 1970-01-01
          • 2017-12-11
          • 2019-03-01
          • 2023-03-04
          • 1970-01-01
          • 2017-05-03
          • 2016-05-05
          相关资源
          最近更新 更多