web-dev-qa-db-ja.com

キャッチされません(約束):TypeError:nullのプロパティ 'component'を読み取ることができません

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の関連オブジェクトの正しいクエリを実行するために、すべての上位変数が必要になります。

助けてくれてありがとう!

21
lmisael

この記事( 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
}

この方法では、ルーターは常にコンポーネントをアプリケーションのルートにあるルーターアウトレットに挿入します。

27
LLai

私がやったのと同じ理由でこれに出くわした人々の利益のためにコメントを追加すると思いました。テンプレートが条件付きレンダリングを使用し、これらの条件が非同期で満たされる場合、フレームワークは条件が満たされる前にマークアップをレンダリングしようとするため、ルーターアウトレットを条件付きマークアップ内に入れることはできません。例えば:

<div *ngIf="someAsyncCall()">
   <header>{{some result from the async call}}</header>
   <router-outlet></router-outlet>
</div>

may非同期呼び出しの終了速度に応じて失敗します。マークアップの静的部分のみを条件付きレンダリングに含める方が常に安全です。次のように:

<div *ngIf="someAsyncCall()">
    <header>{{some result from the async call}}</header>
</div>
<router-outlet></router-outlet>

「ビジーインジケータ」ディレクティブでページ全体をラップすることで、ルーターアウトレットが常に利用可能でないことをほとんど保証しました。後知恵で明らかなようですが、....

4
lje

子ルート構造に興味がある場合。このモデルに従うことができます。これは 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            
      }
    ]
  }
};
1
Manoj De Mel