1

当我单击列表中的特定项目时呈现“产品编辑页面”时出现问题。

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

产品.service.ts

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

上述方法将在我的 Resolver 中调用,如下所示。

产品解析器.service.ts

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

现在的问题是,每当我从列表中单击编辑按钮时,什么都没有发生。这应该被重定向到我的编辑产品页面并使用this.route.snapshot.data['product'].

我通过传递给我的路由来调试enableTracing: true路由,它似乎卡在Router Event: ResolveStart. 有人可以启发我为什么这是这种行为吗?

4

1 回答 1

4

路由器等待 observable 完成。确保在使用take(1)or发出第一个值后完成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;
        }
      })
    );
  }

PS你可以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;
        }),
    ); 
}
于 2018-09-04T05:45:06.717 回答