pasar - Cómo enrutar a un Módulo como hijo de un Módulo-Angular 2 RC 5
rutas angular 5 (7)
Bien, después de jugar con esto durante la mayor parte del fin de semana, lo puse en marcha. Lo que funcionó para mí al final fue hacer lo siguiente:
-
Exporte todas las
Routes
para cada módulo que desee enrutar. No importe ninguno deRouterModule.forChild()
en los módulos secundarios. - Exporte todos los componentes que sean visibles desde las definiciones de ruta del niño en la definición del módulo del niño.
-
Importe (es decir, la palabra clave de
import
mecanografía) todas las rutas secundarias como de costumbre y utilice el operador...
para incorporarlas en la ruta correcta. No pude hacer que funcione con el módulo secundario que define la ruta, pero tenerlo en el padre funciona bien (y es compatible con la carga diferida).
En mi caso, tenía tres niveles en una jerarquía como esta:
-
Raíz (
/
)-
Editor (
editor/:projectId
)-
Consulta (
query/:queryId
) -
Página (
page/:pageId
)
-
Consulta (
-
Frente (
about
)
-
Editor (
Las siguientes definiciones me funcionan para la
/editor/:projectId/query/:queryId
ruta:
// 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''
},
]
}
Las rutas del editor se ven así:
// 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''
}
]
}
Y la parte final para el QueryEditor se ve así:
// app/editor/query/query-editor.routes.ts
{
path: "",
component : QueryEditorHostComponent,
children : [
{ path: ''create'', component : QueryCreateComponent },
{ path: '':queryId'', component : QueryEditorComponent }
]
}
Sin embargo, para que esto funcione, el
Editor
general necesita importar
y
exportar
QueryEditor
y
QueryEditor
necesita exportar
QueryCreateComponent
y
QueryEditorComponent
ya que estos son visibles con la importación.
Si no lo hace, obtendrá errores en la línea del
Component XYZ is defined in multiple modules
.
Tenga en cuenta que la carga diferida también funciona bien con esta configuración, en ese caso, las rutas secundarias no deberían importarse, por supuesto.
Estoy en el proceso de actualización de una aplicación en la que estoy trabajando para el último candidato de lanzamiento de Angular 2. Como parte de este trabajo, intento utilizar la especificación NgModule y migrar todas las partes de mi aplicación a los módulos. En su mayor parte, esto ha ido muy bien con la excepción de un problema con el enrutamiento.
"@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",
Mi aplicación está construida como una composición de módulos, con varios módulos unidos como hijos de un módulo principal. Por ejemplo, tengo un módulo de administración que consta de un módulo de notificaciones, un módulo de usuarios y un módulo de telefonía (por ejemplo). Las rutas a estos módulos deberían verse como ...
/admin/notifications/my-notifications
/admin/users/new-user
/admin/telephony/whatever
En la versión anterior del enrutador, esto era fácil de lograr usando "niños"
export const AdminRoutes: RouterConfig = [
{
path: "Admin",
component: AdminComponent,
Children: [
...UserRoutes,
...TelephonyRoutes,
...NotificationRoutes
]
}
]
En otro archivo, como parte de los submódulos, también definiría las rutas individuales del módulo, es decir
export const UserRoutes: RouterConfig = [
{
path: "users",
component: userComponent,
children: [
{path: "new-user", component: newUserComponent}
]
}
]
Todo esto funcionó muy bien. En el proceso de actualización a Módulos, moví todo a sus propios archivos de enrutamiento individuales, así que ahora estos dos se parecen más a esto
const AdminRoutes: Routes = [
{path: "admin", component: AdminComponent}
]
export const adminRouting = RouterModule.forChild(AdminRoutes)
y
const UserRoutes: Routes = [
path: "users",
component: userComponent,
children: [
{path: "new-user", component: newUserComponent}
]
]
export const userRouting = RouterModule.forChild(UserRoutes)
Con todo eso en su lugar, tengo un UsersModule que importa el UserRouting, y luego un AdminModule que importa el adminRoutes y el UsersModule. Pensé que, dado que UsersModule es hijo de AdminModule, el enrutamiento funcionaría como solía hacerlo. Desafortunadamente, no lo hace, así que termino con una ruta de usuarios que es solo
/users/new-user
en vez de
/admin/users/new-user
Además, debido a esto, el componente de nuevo usuario no se carga en la salida del enrutador de mi componente de administración, lo que desvía el estilo y la navegación de mi aplicación.
Por mi vida, no puedo pensar en cómo hacer referencia a las rutas de mi UserModule como hijos de mi AdminModule. He intentado hacer esto a la antigua usanza y obtengo errores sobre las rutas que se encuentran en dos módulos. Obviamente, dado que esto se lanzó recientemente, la documentación sobre algunos de estos casos es un poco limitada.
¡Cualquier ayuda que alguien pueda brindar sería muy apreciada!
Creo que 2.0.0 rc5 no está interesado ahora. Pero se trabaja en Angular 4, puede ser temprano también.
@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 {}
Tener en cuenta en
loadChildren: () => {...}
.
No es la carga perezosa.
Ver detalles https://github.com/angular/angular/issues/10958
Cuando utiliza ngModules y RC5, la configuración de enrutamiento de su módulo principal no necesita saber nada sobre el enrutamiento de módulos secundarios. Solo tiene que definir las rutas para su módulo principal aquí. Además, debe importar el módulo secundario en su módulo principal. En el módulo secundario, debe definir sus rutas de esta manera:
export const childRoutes: Routes = [
{
path: ''someChild'',
component: SomeChildComponent,
children: [
{ path: '''', component: SomeChildSubComponent1 },
{ path: ''comp1'', component: SomeChildSubComponent1 },
{ path: ''comp2'', component: SomeChildSubComponent2 }
]
}
];
Esto le permitirá tener una URL como / someParent / someChild / comp1, y los componentes se muestran en su enrutador correspondiente. Tenga en cuenta: TIENE QUE descartar un componente para la ruta vacía. De lo contrario, no podrá navegar hacia sus hijos.
Encontré una manera de resolver esto también. Básicamente, estoy definiendo mis rutas de la forma en que solía hacerlo, pero esta vez en el nivel superior del niño. Por ejemplo mi ruta de administrador:
const AdminRoutes: Routes = [
{
path: ''admin'',
component: AdminComponent,
children: [
...setupRoutes
]
}
]
export const adminRouting = RouterModule.forChild(AdminRoutes)
Mi archivo de rutas de configuración se importa desde un área secundaria, que define las rutas propias, incluidos más elementos secundarios. El problema es que este archivo exporta el objeto "Rutas" y no el resultado RouterModule.forChild.
Después de configurarlo, eliminé las rutas secundarias y secundarias de las definiciones de submódulos. Luego tuve que exportar todos los componentes utilizados en las rutas, desde cada uno de los submódulos, al igual que Marcus mencionado anteriormente. Una vez que hice eso, las rutas comenzaron a funcionar como yo quería.
No creo que realmente me guste esta solución, ya que mi módulo principal sabe demasiado sobre las rutas del módulo secundario. Pero al menos es una forma fácil de evitarlo para RC5, y no pierde todos mis componentes por todas partes. Continuaré y marcaré la respuesta de Marcus como la respuesta ya que me puso en el camino correcto.
También conseguí que esto funcionara y, a menos que realmente necesite renderizar todos los componentes principales en la jerarquía, creo que mi solución es mucho más elegante.
La clave para comprender mi enfoque es que todas las rutas, sin importar cuán profundamente anidadas en los módulos se agreguen al módulo raíz.
Ejemplo rápido, digamos que tenemos un
DepartmentModule
y un
EmployeeModule
que nos gustaría navegar usando esta URL
/department/1/employee/2
en ese punto veríamos los detalles del empleado 2.
La configuración de rutas para el
department
en
department.routing.ts
y el
employee
en
employee.routing.ts
no
funcionará de la manera que pretendíamos y notará que puede navegar a
/employee/2
desde el componente raíz, mientras
/department/1/employee/2
se bloqueará (ruta no encontrada). Una configuración de ruta típica en este escenario se vería así:
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 }
]}
];
y
EmployeeModule
sería importado por
DepartmentModule
.
Ahora, como dije, desafortunadamente eso no funciona.
Sin embargo, con solo un cambio:
export const employeeRoutes: Routes = [
{ path: ''department/:id/employee'', component: EmployeeComponent, children: [
{ path: '''', component: EmployeesComponent },
{ path: '':id'', component: EmployeeDetailsComponent }
]}
];
El problema es que
DepartmentModule
ya no está tomando una parte activa tan pronto como navega a la URL de un
employee
, pero aún puede acceder a todos los parámetros desde
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'']);
}
}
Me pregunto si se supone que este es el enfoque oficial, pero por ahora esto funciona para mí hasta el próximo cambio importante del equipo de Angular 2.
Use
loadChildren
.
Está bien.
Pero cuando reinicie el proceso de compilación, obtendrá el error de compilación.
Debe hacer coincidir el símbolo exportado con el
loadChildren
.
import { ChildModule } from ''./child/child.module'';
export function childRouteFactory() {
return ChildModule;
}
...
{
path: ''child'',
loadChildren: childRouteFactory
}
...
Yo tuve el mismo problema.
La respuesta aquí es bastante buena usando loadChildren:
{
path: ''mypath'',
loadChildren : () => myModule
}