Uncaught (in prom): TypeError: Невозможно прочитать свойство 'component' из null
Получение этой ошибки при попытке использовать маршрут nestet в Angular 4:
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 (http://localhost:4200/vendor.bundle.js:77976:71)
at http://localhost:4200/vendor.bundle.js:77954:19
at Array.forEach (native)
at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseChildRoutes (http://localhost:4200/vendor.bundle.js:77953:29)
at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseRoutes (http://localhost:4200/vendor.bundle.js:77985:22)
Это мой код маршрутизации:
const appRoutes: Routes = [
{
path: '',
component: HomeComponent
},
{
path: 'sobre',
component: SobreComponent
},
{
path: 'c/:concurso', component: ConcursoItemComponent
, children: [
{
path: ':cargo',
component: CargoItemComponent,
children: [
{
path: ':disc',
component: DisciplinaItemComponent,
children: [{
path: ':assunto',
component: AssuntoItemComponent
}]
}
]
}
]
},
];
Я хочу сделать следующие вложенные правила, каждый из которых использует переменные для информирования вложенных компонентов каждого маршрута:
/
/С/: Concurso/
/С/: Concurso/: грузы /
/С/: Concurso/: грузы /: дисковые/
/С/: Concurso/: грузы /: дисковые/: Assunto
На каждом уровне мне понадобятся все верхние переменные для правильного запроса связанных объектов API.
Спасибо за любую помощь!
Ответы
Ответ 1
Как говорится в этой статье (https://angular-2-training-book.rangle.io/handout/routing/child_routes.html) при работе с дочерними маршрутами, так же, как вы определяете выход-маршрутизатор для корня вашего приложения, Вы должны определить выход маршрутизатора для своего родительского компонента (в данном случае ConcursoItemComponent. И технически также CargoItemComponent & DisciplinaItemComponent). Таким образом, у вас есть 2 варианта.
- Определите маршрутизатор-выход в компоненте ConcursoItemComponent. Таким образом, маршрутизатор будет знать, где загрузить дочерний компонент (CargoItemComponent), когда пользователь посещает c/: concurso/: cargo
- Не используйте дочерние маршруты и вместо этого создайте все свои маршруты на верхнем уровне маршрутизатора (корень приложения)
{
path: 'c/:concurso,
component: ConcursoItemComponent
},
{
path: 'c/:concurso/:cargo,
component: CargoComponent
},
{
path: 'c/:concurso/:cargo/:disc,
component: DisciplinaItemComponent
},
{
path: 'c/:concurso/:cargo/:disc/:assunto,
component: AssuntoItemComponent
}
Таким образом, маршрутизатор всегда будет вставлять компонент в розетку маршрутизатора в корне приложения.
Ответ 2
Просто подумал, что добавлю комментарий в пользу тех, кто спотыкается об этом по той же причине, что и я. Если ваш шаблон использует условный рендеринг, и эти условия выполняются асинхронно, маршрутизатор-розетка не может находиться внутри условной разметки, потому что инфраструктура может попытаться выполнить разметку до того, как условие будет выполнено. Например:
<div *ngIf="someAsyncCall()">
<header>{{some result from the async call}}</header>
<router-outlet></router-outlet>
</div>
может выйти из строя в зависимости от того, как быстро заканчивается асинхронный вызов. Всегда безопаснее включать только статические части разметки в условном рендеринге. Как в:
<div *ngIf="someAsyncCall()">
<header>{{some result from the async call}}</header>
</div>
<router-outlet></router-outlet>
Я получил бит, обернув всю страницу директивой "Занятый индикатор", которая в значительной степени гарантировала, что маршрутизатор-розетка будет недоступна все время. Кажется очевидным в ретроспективе, но....
Ответ 3
Если кому-то интересно поехать со структурой маршрута Child. Вы могли бы следовать этой модели. Я нашел это в ngx-панировочных сухарях.
const myRoutes : Route[] = {
{
path: '',
component: HomeComponent
},
{
path: 'about',
component: AboutComponent
},
{
path: 'person',
children: [
{
path: '',
component: PersonListComponent
},
{
path: ':id',
component: PersonDetailComponent
}
]
},
{
path: 'folder',
children: [
{
path: '',
component: FolderComponent
},
{
path: ':id',
component: FolderComponent
}
]
}
};