Angular 路由器事件未结束
Posted
技术标签:
【中文标题】Angular 路由器事件未结束【英文标题】:Angular Router Event does not ended 【发布时间】:2019-02-09 01:36:25 【问题描述】:当我单击列表中的特定项目时呈现“产品编辑页面”时出现问题。
我有一个从 firebase firestore 检索特定数据的服务方法。
product.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中被调用,如下图。
product-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);
)
);
product-routing.module.ts
path: 'products/:id/edit',
component: ProductEditComponent,
canActivate: [AuthGuardService],
resolve: product: ProductResolver
现在的问题是,每当我从列表中单击编辑按钮时,什么都没有发生。这应该被重定向到我的编辑产品页面并使用 this.route.snapshot.data['product']
填充文本框中的所有数据。
我通过将enableTracing: true
传递给我的路由来调试路由,它似乎卡在Router Event: ResolveStart
中。有人可以启发我为什么这是这种行为吗?
【问题讨论】:
不要为 firebase 查询创建新的 observable,而是使用fromPromise
,这在理解和代码数量方面效率更高。
@trichetriche 你能发布一些与上述代码相关的 fromPromise 的代码快照吗?谢谢!
或者你可以make a quick google search ...
【参考方案1】:
路由器等待 observable 完成。确保在使用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;
),
);
【讨论】:
这行得通!那么,在我上面的服务中,我也可以调用“observer.complete()”来完成observable吗?是否需要调用 complete() ?非常感谢! @klaydze 是的,你也可以使用 observable.complete() 。但是,您必须处理 onSnapshot 中的错误情况,例如observable.error(error) 我尝试了您在getProduct
方法中提供的更新代码,但我很难实现它,因为 onSnapshot
应该有一个基于 firebase 文档的参数
@klaydze 是的,这仅在 guid 是您的实际文档 ID 时才有意义以上是关于Angular 路由器事件未结束的主要内容,如果未能解决你的问题,请参考以下文章