私は最新のAngular 2リリース候補に取り組んでいるアプリケーションをアップグレードしています。この作業の一環として、NgModule仕様を使用し、アプリケーションのすべての部分をモジュールに移行しようとしています。ほとんどの場合、これはルーティングに関する問題を除いて非常にうまくいっています。
"@angular/common": "2.0.0-rc.5",
"@angular/compiler": "2.0.0-rc.5",
"@angular/core": "2.0.0-rc.5",
"@angular/forms": "0.3.0",
"@angular/http": "2.0.0-rc.5",
"@angular/platform-browser": "2.0.0-rc.5",
"@angular/platform-browser-dynamic": "2.0.0-rc.5",
"@angular/router": "3.0.0-rc.1",
私のアプリはモジュールの構成として構築され、いくつかのモジュールが親モジュールの子として一緒に接着されています。たとえば、通知モジュール、ユーザーモジュール、およびTelphonyモジュール(たとえば)で構成される管理モジュールがあります。これらのモジュールへのルートは次のようになります。
/admin/notifications/my-notifications
/admin/users/new-user
/admin/telephony/whatever
ルータの以前のリリースでは、これは "子供"を使って簡単に達成できました
export const AdminRoutes: RouterConfig = [
{
path: "Admin",
component: AdminComponent,
Children: [
...UserRoutes,
...TelephonyRoutes,
...NotificationRoutes
]
}
]
別のファイルでは、サブモジュールの一部として、個々のモジュールルートも同様に定義します。
export const UserRoutes: RouterConfig = [
{
path: "users",
component: userComponent,
children: [
{path: "new-user", component: newUserComponent}
]
}
]
これはすべてうまくいった。 Modulesにアップグレードする過程で、私はすべてを自分の個別のルーティングファイルに入れ替えました
const AdminRoutes: Routes = [
{path: "admin", component: AdminComponent}
]
export const adminRouting = RouterModule.forChild(AdminRoutes)
そして
const UserRoutes: Routes = [
path: "users",
component: userComponent,
children: [
{path: "new-user", component: newUserComponent}
]
]
export const userRouting = RouterModule.forChild(UserRoutes)
そのすべてを整えて、私はuserRoutingをインポートするUsersModuleを持っていて、次にadminRoutesとUsersModuleをインポートするAdminModuleを持っています。私の考えは、UsersModuleはAdminModuleの子であるため、ルーティングは以前と同じように動作します。残念ながら、そうではありませんので、私はユーザールートで終わります
/users/new-user
の代わりに
/admin/users/new-user
さらに、これにより、新しいユーザーコンポーネントは、自分のアプリケーションのスタイリングとナビゲーションをスローする管理コンポーネントのルーターアウトレットに読み込まれません。
私の人生のために、自分のUserModuleのルートをAdminModuleの子として参照する方法を考え出すことができません。私は古い方法でこれをやろうとしていて、ルートが2つのモジュールにあることについてのエラーを得る。明らかにこれは新しくリリースされているので、これらのケースのいくつかのドキュメントは少し限られています。
誰でも助けることができれば大いに感謝します!
さて、週末のより良いところでこれを騒がした後、私はそれを私の最後に走らせました。最終的に私のために働いたのは次のことでした:
Routes
あなたがルーティングしたいすべてのモジュールのために。いずれかをインポートしないでくださいRouterModule.forChild()
子モジュール内にある。import
キーワード)を使用して...
オペレータはこれらを正しい経路の下に組み込むことができます。私はそれがパスを定義する子モジュールで動作するようにすることはできませんでしたが、親にそれを持たせることはうまく動作します(遅延ロードと互換性があります)。私の場合、私はこのような階層に3つのレベルを持っていました:
/
)editor/:projectId
)query/:queryId
)page/:pageId
)about
)次の定義は、/editor/:projectId/query/:queryId
パス:
// app.routes.ts
import {editorRoutes} from './editor/editor.routes'
// Relevant excerpt how to load those routes, notice that the "editor/:projectId"
// part is defined on the parent
{
path: '',
children: [
{
path: 'editor/:projectId',
children: [...editorRoutes]
//loadChildren: '/app/editor/editor.module'
},
]
}
エディタルートは次のようになります。
// app/editor/editor.routes.ts
import {queryEditorRoutes} from './query/query-editor.routes'
import {pageEditorRoutes} from './page/page-editor.routes'
{
path: "", // Path is defined in parent
component : EditorComponent,
children : [
{
path: 'query',
children: [...queryEditorRoutes]
//loadChildren: '/app/editor/query/query-editor.module'
},
{
path: 'page',
children: [...pageEditorRoutes]
//loadChildren: '/app/editor/page/page-editor.module'
}
]
}
そして、QueryEditorの最後の部分は次のようになります:
// app/editor/query/query-editor.routes.ts
{
path: "",
component : QueryEditorHostComponent,
children : [
{ path: 'create', component : QueryCreateComponent },
{ path: ':queryId', component : QueryEditorComponent }
]
}
しかし、この作業を行うためには、一般Editor
輸入する必要があるそして輸出するQueryEditor
そしてそのQueryEditor
輸出する必要があるQueryCreateComponent
そしてQueryEditorComponent
これらはインポート時に表示されるためです。これをしないと、Component XYZ is defined in multiple modules
。
遅延ロードもこの設定でうまくいくことに注意してください。この場合、子ルートはもちろんインポートされるべきではありません。
私も同じ問題がありました。
loadChildrenを使用すると、ここでの答えはかなり良いです:
{
path: 'mypath',
loadChildren : () => myModule
}
https://github.com/angular/angular/issues/10958
私もこれを解決する方法を見つけました。基本的には、これまでのように私のルートを定義していますが、今回はトップレベルの子レベルで定義しています。たとえば、私の管理ルート:
const AdminRoutes: Routes = [
{
path: 'admin',
component: AdminComponent,
children: [
...setupRoutes
]
}
]
export const adminRouting = RouterModule.forChild(AdminRoutes)
私のセットアップルートファイルは、より多くの子供を含む、それ自身のルートを定義するサブエリアからインポートされます。 catchは、このファイルがRouterModule.forChildの結果ではなく、 "Routes"オブジェクトをエクスポートするということです。
それがセットアップされた後、サブモジュール定義から子ルートと子子ルートが削除されました。私はその後、上記のMarcusのように、各サブモジュールからルートに使用されているすべてのコンポーネントをエクスポートしなければなりませんでした。私がそれをしたら、私は彼らが欲しいのと同じようにルートが働き始めました。
私の親モジュールは子モジュールのルートについてあまり知っていないので、私はこのソリューションが本当に好きだとは思わない。しかし、少なくともRC5のためのそれを回避するための簡単な方法、それはすべての場所のすべてのコンポーネントを漏らすことはありません。彼が私を正しい軌道に乗せたので、私は先に進み、答えとしてマークスの答えをマークします。
私は2.0.0 rc5は今興味がないと思う。しかし、角度4で働いている、早すぎるかもしれません。
@NgModule({
imports: [
RouterModule.forRoot([
{path: "", redirectTo: "test-sample", pathMatch: "full"},
{
path: "test-sample",
loadChildren: () => TestSampleModule
}
])
],
exports: [RouterModule],
declarations: []
})
export class AppRoutingModule{}
@NgModule({
imports: [
RouterModule.forChild([{
path: "",
component: TestSampleComponent,
children: [
{path: "", redirectTo: "home", pathMatch: "full"},
{
path: "home",
loadChildren: () => HomeModule
},
{
path: "about",
loadChildren: () => AboutModule
}
]
}
])
],
exports: [RouterModule],
declarations: []
})
export class TestSampleRoutingModule {}
@NgModule({
imports: [RouterModule.forChild([{
path: "",
component: AboutComponent
}
])],
exports: [RouterModule]
})
export class AboutRoutingModule {}
アカウントを取るloadChildren: () => {...}
。それは怠惰な読み込みではありません。
詳細はこちらをご覧くださいfeat:サポートNgModules階層sans Lazy Loading
ngModulesとRC5を使用している場合、親モジュールのルーティング設定では、子モジュールのルーティングについて何も知る必要はありません。ここでは、親モジュールのルートを定義するだけです。 さらに、子モジュールを親モジュールにインポートする必要があります。 子モジュールでは、このようにルートを定義する必要があります。
export const childRoutes: Routes = [
{
path: 'someChild',
component: SomeChildComponent,
children: [
{ path: '', component: SomeChildSubComponent1 },
{ path: 'comp1', component: SomeChildSubComponent1 },
{ path: 'comp2', component: SomeChildSubComponent2 }
]
}
];
これにより、/ someParent / someChild / comp1のようなURLが作成され、コンポーネントは対応するルータのアウトレットに表示されます。 注:空のパスのコンポーネントを宣言する必要があります。それ以外の場合は、子供たちに移動することはできません。
私はこれもうまく動作するようにしました。階層のすべての親コンポーネントを実際にレンダリングする必要がない限り、私のソリューションははるかにエレガントです。
私のアプローチを理解するための鍵は、ルートモジュールにモジュールがどれくらい深く入れ子になっていても、すべてのルートが必要であるということです。簡単な例ですが、DepartmentModule
とEmployeeModule
このURLを使用してナビゲートしたい
/department/1/employee/2
その時点で従業員2の詳細が表示されます。ルートの設定department
にdepartment.routing.ts
そしてemployee
にemployee.routing.ts
意志ない私たちが意図した通りに働くと、あなたは
/employee/2
ルートコンポーネントから
/department/1/employee/2
クラッシュします(ルートが見つかりません)。このシナリオでの一般的なルート設定は、次のようになります。
export const departmentRoutes: Routes = [
{ path: 'department', component: DepartmentComponent, children: [
{ path: '', component: DepartmentsComponent },
{ path: ':id', component: DepartmentDetailsComponent }
]}
];
export const employeeRoutes: Routes = [
{ path: 'employee', component: EmployeeComponent, children: [
{ path: '', component: EmployeesComponent },
{ path: ':id', component: EmployeeDetailsComponent }
]}
];
そしてEmployeeModule
によって輸入されるDepartmentModule
。今、私が言ったように、残念ながらそれは働かない。
ただし、変更を1回だけ行うと、次のようになります。
export const employeeRoutes: Routes = [
{ path: 'department/:id/employee', component: EmployeeComponent, children: [
{ path: '', component: EmployeesComponent },
{ path: ':id', component: EmployeeDetailsComponent }
]}
];
キャッチは、それですDepartmentModule
すぐにあなたはemployee
URLにはアクセスできますが、引き続きすべてのパラメータにアクセスできますActivatedRoute
:
export class EmployeeDetailsComponent {
departmentId: number;
employeeId: number;
constructor(route: ActivatedRoute) {
route.parent.params.subscribe(params =>
this.departmentId= +params['id'])
route.params.subscribe(params =>
this.employeeId= +params['id']);
}
}
私はこれが公式のアプローチになっているのだろうかと思っていますが、今はこれがAngular 2チームの次の急変する変更まで私の仕事です。
つかいますloadChildren
。それで大丈夫です。しかし、ビルドプロセスを再開すると、ビルドエラーが発生します。エクスポートされたシンボルは、loadChildren
。
import { ChildModule } from './child/child.module';
export function childRouteFactory() {
return ChildModule;
}
...
{
path: 'child',
loadChildren: childRouteFactory
}
...
loadChildren
モジュールに明示的に言及できるルート上のプロパティ。ドキュメントは遅延読み込みのコンテキストでしか話しませんが... - Marcus RiemerloadChildren
非常にうまく説明されています。 - Hinrich