Angular:无法读取null的属性'component'

时间:2017-08-09 16:30:39

标签: angular angular-ui-router

我有一个奇怪的问题。我有一个基本的路由配置:

const appRoutes: Routes = [
  {path: '', redirectTo: '/search', pathMatch: 'full'},
  {path: 'login', component: LoginComponent },
  {path: 'dashboard', component: DashboardComponent, canActivate: [OnlyLoggedInGuard]},
  {path: 'search', component: SearchComponent, canActivate: [OnlyLoggedInGuard]}
];

在应用HTML上,我有条不紊地导入路由器插座:

<div *nfIf="condition">
...
<router-outlet></router-outlet>
...
</div>
<div *nfIf="!condition">
... another dom construction
<router-outlet></router-outlet>
...
</div>

我拦截(带有HttpInterceptor)HTTP 401错误以重定向到登录页面。在我的http拦截器中的某些意义上我有这个意思:

this._router.navigate(['/login', {error:'I am an error message'}]);

当我在仪表板上并且发生401时,我正确地重定向到具有正确错误参数的登录页面。 但是,当我在登录页面上并且从服务器获得401时,我遇到以下错误:

core.es5.js:1020 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'component' of null
TypeError: Cannot read property 'component' of null
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseRoutes (router.es5.js:4343)
    at router.es5.js:4305
    at Array.forEach (<anonymous>)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseChildRoutes (router.es5.js:4304)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverse (router.es5.js:4261)
    at MapSubscriber.project (router.es5.js:4100)
    at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:77)
    at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:143)
    at InnerSubscriber.webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseRoutes (router.es5.js:4343)
    at router.es5.js:4305
    at Array.forEach (<anonymous>)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseChildRoutes (router.es5.js:4304)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverse (router.es5.js:4261)
    at MapSubscriber.project (router.es5.js:4100)
    at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:77)
    at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:143)
    at InnerSubscriber.webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
    at resolvePromise (zone.js:783)
    at resolvePromise (zone.js:754)
    at zone.js:831
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
    at Object.onInvokeTask (core.es5.js:3881)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:191)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
    at invokeTask (zone.js:1370)

2 个答案:

答案 0 :(得分:7)

确定。我设法解决了这个问题。我不完全明白,但这是我找到的:

  • Cannot read property 'component' of null仅在应用HTML中包含一次时router-outlet消失(例如:与在{{的多个分支中的每个分支中包含router-outlet相反1}}条件)

  • 当我从

  • 更改ng-if的条件包含时

这种形式:

router-outlet

到这种形式:

    <div *nfIf="condition">
        <router-outlet></router-outlet>
    </div>
    <div *nfIf="!condition">
        <router-outlet></router-outlet>
    </div>

我没有问题从登录页面导航到带参数的登录页面。

答案 1 :(得分:0)

如果要更改路由器出口周围的DOM,可以创建一个处理该组件并使用ng-content放置路由器出口的组件:

<!-- layout.component.html -->
<div *ngIf="condition" style="background: yellow">
  <ng-container *ngTemplateOutlet="ngContent"></ng-container>
</div>

<div *ngIf="!condition" style="background: green">
  <ng-container *ngTemplateOutlet="ngContent"></ng-container>
</div>

<ng-template #ngContent>
  <ng-content></ng-content>
</ng-template>

然后像下面这样在app.component.html中使用它:

<app-layout [condition]="condition">
  <router-outlet></router-outlet>
</app-layout>

尽管如此,我仍然不得不对*ngIf做些事情,因为当我在layout.component.html中添加其中两个时,它开始抱怨。我不知道这是否是您要找的东西,但这是堆栈炸弹:https://stackblitz.com/edit/angular-r1pvca