我正在尝试实现一个解析器,以便在加载组件之前解析我的 API 数据。从我的服务中的 HTTP 请求返回的 observable 永远不会完成,导致路由挂起。我已经搜索了教程和 Angular 文档,看看我做错了什么。有任何想法吗?我已经概括了一些代码(只是一些命名),但不应该影响它的工作方式。
这是我的解析器服务:
@Injectable({
providedIn: 'root',
})
export class PageResolverService implements Resolve<any> {
constructor(
private service: MyAPIService,
private http: HttpClient
) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<any> | Promise<any> | any {
return this.service.getPage(route.url[0].path);
}
}
这是我的路由模块(它不是 app-routing.module.ts
,而是一个“子”):
const routes: Routes = [
{
path: 'my-path',
component: MyComponent,
resolve: {
page: ResolverService,
},
},
{
path: '',
component: OtherComponent,
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [ResolverService],
})
export class RoutingModule {}
我的服务:
@Injectable({
providedIn: 'root',
})
export class MyAPIService {
constructor(private http: HttpClient) {}
public getPage = (slug: string): Observable<Page[]> => {
const uri = "https://my.com/URI"
return this.http.get<Page[]>(uri);
};
}
还有我的组件:
export class MyComponent implements OnInit {
page: Page = null;
constructor(
private activatedRoute: ActivatedRoute
) {
this.activatedRoute.data.subscribe((data) => {
console.log(data)
this.page = data.page[0];
});
}
ngOnInit(): void {}
}
我什至无法在组件构造函数中向控制台输出任何内容。如果我将解析器更改为
,我可以获得数据return of(this.service.getPage(route.url[0].path));
并将我的组件更改为
this.activatedRoute.data.subscribe((data) => {
console.log(data);
data.page.subscribe((page) => {
this.page = page[0];
});
});
但是在我的组件加载后数据加载,我在控制台中收到错误,提示它无法读取 property "title" of null
(page
被初始化为 null)。
答案 0 :(得分:0)
首先将和平转移到ngOnInit
this.activatedRoute.data.subscribe((data) => {
console.log(data)
this.page = data.page[0];
});
去掉类中的箭头函数。
您的端点返回什么,页面数组还是仅页面?
设置正确的返回类型 并添加 tap 运算符来调试您的端点
public getPage(slug: string): Observable<Page[]> {
const uri = "https://my.com/URI"
return this.http.get<Page[]>(uri).pipe(tap(console.log));
};
Angular 的 httpClient 在发出值时完成,如果您想手动完成 observable,请尝试 take(1)
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<any> | Promise<any> | any {
return this.service.getPage(route.url[0].path).pipe(take(1));
}
<块引用>
我什至无法在组件构造函数中向控制台输出任何内容。如果我将解析器更改为
,我可以获得数据不要做嵌套的 observables
return of(this.service.getPage(route.url[0].path));
基本上,您将 http 请求包装在 Observable 中,然后订阅组件两次,其中第二个订阅是 http 请求
this.activatedRoute.data.subscribe((data) => { // this.activatedRoute.data = of()
console.log(data);
data.page.subscribe((page) => { // data.page = this.service.getPage()
this.page = page[0]; // this subscription trigger http request
});
});
答案 1 :(得分:0)
这是我找到的解决方案 - https://stackoverflow.com/a/56280405/11790081
事实证明这是 Angular Universal 和 SSR 的问题。只需添加对 isPlatformBrowser(this.platformId)
的检查以在解析器中产生条件返回就解决了我的问题。