如何仅在数据通过Angular解析器加载时才渲染组件



目前,组件在数据加载之前显示(通过解析器),我将改变它。

我想要Guard之类的东西。→仅在数据存储时呈现。

我有三个文件:http。服务类别。服务和解析器。

http。服务只有HTTP调用类别。服务有方法"调度"。它具有获取数据并订阅它的整个逻辑。

我的解析器:

@Injectable({ providedIn: 'root' })
export class ProductsCategoriesResolver implements Resolve<any> {
constructor(private categoriesService: CategoriesService) {}
resolve(): void {
this.categoriesService.dispatch();
}
}

分类服务

@Injectable({ providedIn: 'root' })
export class CategoriesService implements OnDestroy {
categories$: BehaviorSubject<CategoryModel[] | false> = new BehaviorSubject(false);
categoryTitle$ = new BehaviorSubject(null);
private subscriptions = new Subscription();
constructor(private httpService: HttpService) {}
dispatch(): void {
this.subscriptions.add(
this.httpService
.getCategories(12)
.pipe(tap((categores) => this.categories$.next(categores)))
.subscribe(),
);
}
ngOnDestroy(): void {
this.subscriptions.unsubscribe();
}
}

http服务
@Injectable({
providedIn: 'root',
})
export class HttpService {
constructor(private httpClient: HttpClient) {}
getCategories(limit: number): Observable<CategoryModel[]> {
const params: HttpParams = new HttpParams().append('limit', limit.toString());
return this.httpClient.get<ApiResponse<CategoryModel[]>>(`api/public/categories`, { params }).pipe(
map((response) => response.data),
map((categories) => {
return categories.map((category) => {
category.image = {
url: `/assets/images/products/product_${Math.floor(Math.random() * 4) + 1}.png`,
};
return category;
});
}),
);
}
}

路线:

const routes: Routes = [
{
path: '',
redirectTo: 'page/1',
pathMatch: 'full',
},
{
path: 'page/:pageNumber',
component: ProductsComponent,
resolve: {
products: ProductsCategoriesResolver,
},
},

您的设置实际上是您想要的行为所需要的唯一东西。解析器旨在延迟导航,直到为路由定义的所有解析器都返回结果(无论是同步的还是异步的)。你的解析器不返回任何东西,所以你的导航会立即发生,而从服务中获取数据只会在后台作为副作用发生。

你似乎也混淆了很多好的技术,因为它们并不是真的要一起工作(比如你在categories-service中的显式订阅管理)。这不会伤害到你,但是当请求结束时,通过Angular HttpClientModule的HttpClient的请求就会完成,而你的服务是在应用的root注入器中提供的,这意味着OnDestroy实际上永远不会被调用(直到用户关闭网站)。

你可以这样修改你的解析器:

@Injectable({ providedIn: 'root' })
export class ProductsCategoriesResolver implements Resolve<Observable<CategoryModel[]>> {
constructor(private categoriesService: CategoriesService) {}
resolve(): Observable<CategoryModel[]> {
this.categoriesService.dispatch();
return this.categoriesService.categories$.pipe(
filter(categories => !!categories),
take(1)
);
}
}

这意味着解析器只会完成,导航只会发生,一旦类别列表已被获取至少一次(和行为主题的值已从false更改为CategoryModel列表)。

做注意这意味着下一个请求的导航将立即发生,因为BehaviorSubject仍然保存上一个请求的值,所以需要做更多的工作,您可能需要考虑进一步更改实现。

看一下Resolve的官方文档,因为它有更多的内容(你可以访问路由快照中的数据,如果你只把它用于这个目的,就会使BehaviorSubject过时)。

最新更新