带解析器的Angular 7路线不会加载组件

crg*_*den 2 rxjs angular angular7

我遇到了一个Angular 7问题,该问题是在路由上具有解析器的模块的子组件无法加载。

app-routing.module.ts

{
  path: 'Account',
  loadChildren: './account/account.module#AccountModule'
}
Run Code Online (Sandbox Code Playgroud)

account-routing.module.ts

{
  path: 'Profile',
  component: ProfileComponent,
  resolve: {
    profile: ProfileResolver
  }
}
Run Code Online (Sandbox Code Playgroud)

profile.resolver.ts

@Injectable()
export class ProfileResolver implements Resolve<Profile> {

  constructor(private readonly accountService: AccountService) {
  }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Profile> {
    return this.accountService.profile();
  }
}
Run Code Online (Sandbox Code Playgroud)

profile.component.ts

@Component({
?
})
export class ProfileComponent implements OnInit {

  model: Profile;

  constructor(private readonly route: ActivatedRoute) {
  }

  ngOnInit(): void {
    this.model = this.route.snapshot.data['profile'] as Profile;
  }
}
Run Code Online (Sandbox Code Playgroud)

account.service.ts

@Injectable()
export class AccountService {

  constructor(protected readonly http: HttpClient) {
  }

  profile(): Observable<Profile> {
    return this.http.get<Profile>(`${environment.apiUrl}/Account/Profile`);
  }
}
Run Code Online (Sandbox Code Playgroud)

行为是,当导航到时/Account/Profile,将ProfileResolver调用,击中服务器,并获得与该Profile对象的200响应(我可以在“网络”选项卡中看到它),然后...什么都没有。constructorngOnInit方法都不ProfileComponent被调用。

如果我ProfileResolver从中删除AccountRoutingModuleAccountService直接从ngOnInit方法中调用,则它会起作用。但是,在等待响应时,模板中存在许多模板解析错误(这就是我要使用的全部原因resolve)。

要使解析器与这些模块一起使用,我还需要做些其他事情吗?

这也可能是与此处所述相同的问题:Angular Router不会使用分解器加载组件

更新:我打开,enableTracing以便可以看到发生了什么。这是输出:

Router Event: NavigationStart
NavigationStart(id: 2, url: '/Account/Profile')
NavigationStart {id: 2, url: "/Account/Profile", navigationTrigger: "imperative", restoredState: null}

Router Event: RoutesRecognized
RoutesRecognized(id: 2, url: '/Account/Profile', urlAfterRedirects: '/Account/Profile', state: Route(url:'', path:'') { Route(url:'Account', path:'Account') { Route(url:'Profile', path:'Profile') }  } )
RoutesRecognized {id: 2, url: "/Account/Profile", urlAfterRedirects: "/Account/Profile", state: RouterStateSnapshot}

Router Event: GuardsCheckStart
GuardsCheckStart(id: 2, url: '/Account/Profile', urlAfterRedirects: '/Account/Profile', state: Route(url:'', path:'') { Route(url:'Account', path:'Account') { Route(url:'Profile', path:'Profile') }  } )
GuardsCheckStart {id: 2, url: "/Account/Profile", urlAfterRedirects: "/Account/Profile", state: RouterStateSnapshot}

Router Event: ChildActivationStart
ChildActivationStart(path: '')
ChildActivationStart {snapshot: ActivatedRouteSnapshot}

Router Event: ActivationStart
ActivationStart(path: 'Profile')
ActivationStart {snapshot: ActivatedRouteSnapshot}

Router Event: GuardsCheckEnd
GuardsCheckEnd(id: 2, url: '/Account/Profile', urlAfterRedirects: '/Account/Profile', state: Route(url:'', path:'') { Route(url:'Account', path:'Account') { Route(url:'Profile', path:'Profile') }  } , shouldActivate: true)
GuardsCheckEnd {id: 2, url: "/Account/Profile", urlAfterRedirects: "/Account/Profile", state: RouterStateSnapshot, shouldActivate: true}

Router Event: ResolveStart
ResolveStart(id: 2, url: '/Account/Profile', urlAfterRedirects: '/Account/Profile', state: Route(url:'', path:'') { Route(url:'Account', path:'Account') { Route(url:'Profile', path:'Profile') }  } )
ResolveStart {id: 2, url: "/Account/Profile", urlAfterRedirects: "/Account/Profile", state: RouterStateSnapshot}
Run Code Online (Sandbox Code Playgroud)

因此,似乎该ResolveEnd事件从未触发。我发现了这个问题:如果模块为lazy,则路由器的ActivatedRoute data返回空{}。似乎可能是相关的,但我不确定如何在此实施此修复程序。

crg*_*den 5

我再次查阅了“ 路由和导航”指南,并更改了我的解析器,使其看起来像在这里一样:

profile.resolver.ts

@Injectable()
export class ProfileResolver implements Resolve<Profile> {

  constructor(private readonly accountService: AccountService) {
  }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Profile> {
    return this.accountService.profile().pipe(
      take(1),
      map((profile: Profile) => profile));
  }
}
Run Code Online (Sandbox Code Playgroud)

关键是添加take(1)。没有这个,ResolveEnd事件就永远不会被触发而Router只是挂起。