【问题标题】:Uncaught (in promise): TypeError: Cannot read property 'component' of null未捕获(承诺中):TypeError:无法读取 null 的属性“组件”
【发布时间】:2017-12-01 01:45:30
【问题描述】:

在 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
                        }]
                    }
                ]

            }
        ]
    },

];

我想做如下嵌套规则,每一个都使用变量来通知每条路由的嵌套组件:

/

/c/:concurso/

/c/:concurso/:cargo/

/c/:concurso/:cargo/:disc/

/c/:concurso/:cargo/:disc/:assunto

在每个级别上,我都需要所有上层变量来正确查询 API 的相关对象。

感谢您的帮助!

【问题讨论】:

  • 您拉入路由文件的组件之一是否可能不正确?也许它是从错误的路径导入的?
  • 好吧,我检查了导入路径,显然它们都是正确的。代码编译良好并且运行良好,直到 /c/:concurso/。错误发生在 /c/:concurso/:cargo/ 我还取出了组件构造函数中的所有 DI 并没有帮助...我的路由代码是否正确?
  • 你的 ConcursoItemComponent 中有 标签吗?
  • 不,我在主应用程序组件中有一个插座。
  • 当您分配给模型时来自后端的某些数据为空时。模型对象被破坏。

标签: javascript angular routes angular2-routing


【解决方案1】:

正如本文 (https://angular-2-training-book.rangle.io/handout/routing/child_routes.html) 所述,在处理子路由时,就像您为应用程序的根定义路由器出口一样,您必须为父组件定义路由器出口(在本例中为 ConcursoItemComponent . 从技术上讲,还有 CargoItemComponent 和 DisciplinaItemComponent) 所以你有 2 个选项。

  • 在 ConcursoItemComponent 中定义一个路由器插座。这样当用户访问 c/:concurso/:cargo 时,路由器就会知道在哪里加载子组件(CargoItemComponent)
  • 不要使用子路由,而是将所有路由设置在顶级路由器级别(应用程序的根目录)
{
    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
}

这样路由器将始终将组件插入到应用程序根目录的路由器插座中。

【讨论】:

  • 谢谢!!我使用了第二个选项,它工作得很好!显然,当我想要嵌套的 portlet 时,使用子路由更适合?这里不是这种情况,我希望通过面包屑显示层次结构。
  • 我还必须在每条路由中添加 pathMatch:'full' 以使内部路由正常工作。
  • @lmisael 有趣的是,您需要 pathMatch: 'full' 才能工作。你是对的,当你想嵌套出口时,你需要子路线。
  • 嗨,我在使用 angular 5 时遇到了同样的问题。由于嵌套路由,我无法避免子路由还有其他可能的解决方案吗?
  • @Imisael 你能输入你的代码吗?如何为您的案例定义子路由?
【解决方案2】:

如果有人有兴趣使用子路由结构。你可以遵循这个模型。我在ngx-breadcrumbs 中找到了这个。

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            
      }
    ]
  }
};

【讨论】:

    【解决方案3】:

    只是想我会添加评论,以帮助那些出于与我相同的原因偶然发现此问题的人。如果您的模板使用条件渲染,并且这些条件是异步满足的,则路由器插座不能在条件标记内,因为框架可能会在满足条件之前尝试渲染标记。例如:

    <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>
    

    我通过将整个页面包装在一个“忙指示符”指令中得到了一点好处,这几乎可以保证路由器插座不会一直可用。事后看来似乎很明显,但是....

    【讨论】:

    • 它的工作,但使用这种方法,页面是从头开始显示的。要避免这种情况怎么办??
    猜你喜欢
    • 2018-04-18
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多