代码之家  ›  专栏  ›  技术社区  ›  klaydze

角路由器事件未结束

  •  1
  • klaydze  · 技术社区  · 6 年前

    我有一个来自服务的方法,它从firebase firestore检索特定的数据。

    /**
    * Get specific product
    */
    getProduct(guid: string): Observable<IProduct> {
    return new Observable((observer) => {
          this.firebaseDb.collection('products')
            .doc('XNRkodfbiRoKc2DYPA3o')
            .onSnapshot((querySnapshot) => {
    
              let product: IProduct;
              product = <IProduct>querySnapshot.data();
              product.guid = guid;
    
              observer.next(product);
    
            }, (error) => console.log(error.message));
        });
    }
    

    上面的方法将在我的解析器中调用,如下所示。

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IProduct> {
    const id = route.params['id'];
    
    return this.productService.getProduct(id)
                  .pipe(
                    map(product => {
                      if (product) {
                        return product;
                      }
                      console.log(`Product was not found: ${id}`);
                      this.router.navigate(['/products']);
                      return null;
                    }),
                    catchError(error => {
                      console.log(`Retrieval error: ${error}`);
                      return of(null);
                    })
                  );
    }
    

    产品-路由.module.ts

      {
        path: 'products/:id/edit',
        component: ProductEditComponent,
        canActivate: [AuthGuardService],
        resolve: { product: ProductResolver }
      }
    

    现在的问题是,每当我从列表中单击edit按钮时,什么都不会发生。这应该是重定向到我的编辑产品页,并填写所有的数据从文本框使用 this.route.snapshot.data['product'] .

    enableTracing: true 我的路线好像被卡住了 Router Event: ResolveStart . 有人能告诉我为什么会这样吗?

    1 回复  |  直到 6 年前
        1
  •  4
  •   DarkLeafyGreen    6 年前

    路由器等待可观察到的完成。确保在使用发出第一个值之后完成 take(1) first() . 例如。:

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IProduct> {
        return this.productService.getProduct(route.paramMap.get('id')).pipe(
          take(1),
          map(product => {
            if (!product) {
              // noinspection JSIgnoredPromiseFromCall
              this.router.navigate(['/404']);
              return null;
            } else {
              return product;
            }
          })
        );
      }
    

    顺便说一下,你可以清理你的房间 getProduct 方法如下:

    getProduct(guid: string): Observable<IProduct> {
        return from(this.firebaseDb.collection('products').doc('XNRkodfbiRoKc2DYPA3o').onSnapshot()).pipe(
            map((snapshot:any) => {
                const product = <IProduct>snapshot.data();
                product.guid = guid;
                return product;
            }),
        ); 
    }