parametros - formularios en angular 6
Cómo usar.forRoot() dentro de la jerarquía de módulos de características (3)
¿Alguien puede aclararme cómo debo estructurar la jerarquía de múltiples módulos de características anidadas con llamadas .forRoot ()?
Por ejemplo, ¿qué pasa si tengo módulos como este?
- MainModule
- SharedModule
- FeatureModuleA
- FeatureModuleA1
- FeatureModuleA2
- FeatureModuleB
Todos los módulos de características tienen funciones estáticas .forRoot ().
¿Cómo debo definir FeatureModuleA con de alguna manera "transferir" las funciones .forRoot ()?
@NgModule({
imports: [
//- I can use .forRoot() calls here but this module not the root module
//- I don''t need to import sub-modules here, FeatureA only a wrapper
//FeatureModuleA1.forRoot(), //WRONG!
//FeatureModuleA2.forRoot(), //WRONG!
],
exports: [
//I cannot use .forRoot() calls here
FeatureModuleA1,
FeatureModuleA2
]
})
class FeatureModuleA {
static forRoot(): ModuleWithProviders {
return {
//At this point I can set any other class than FeatureModuleA for root
//So lets create a FeatureRootModuleA class: see below!
ngModule: FeatureModuleA //should be: FeatureRootModuleA
};
}
}
Puedo crear otra clase para uso raíz y luego configurarla dentro de la función forRoot () de FeatureModuleA:
@NgModule({
imports: [
//Still don''t need any sub module within this feature module
]
exports: [
//Still cannot use .forRoot() calls but still need to export them for root module too:
FeatureModuleA1,
FeatureModuleA2
]
})
class FeatureRootModuleA { }
Pero, ¿cómo puedo "transferir" las llamadas .forRoot () dentro de este módulo especial?
Como veo, necesito importar todos los submódulos directamente en mi MainModule raíz y llamar a .forRoot () para cada uno de ellos:
@NgModule({
imports: [
FeatureModuleA1.forRoot(),
FeatureModuleA2.forRoot(),
FeatureModuleA.forRoot(),
SharedModule.forRoot()
]
})
class MainModule { }
Estoy en lo cierto? Antes de responder, eche un vistazo a este archivo: https://github.com/angular/material2/blob/master/src/lib/module.ts
Como sé, este repositorio mantenido por el equipo angular oficial. Entonces resuelven lo anterior con solo importar todas las llamadas .forRoot () dentro de un módulo especial MaterialRootModule. ¿Realmente no entiendo cómo se aplicaría a mi propio módulo raíz? ¿Qué significa realmente la raíz y .forRoot aquí? ¿Es eso relativo al paquete y no al proyecto web real?
Como se mencionó anteriormente, es importante tener en cuenta los módulos con carga diferida porque un servicio compartido podría usarse en un módulo con carga diferida, pero si ese servicio ya fue utilizado e instanciado por otro módulo, entonces habrá dos instancias, por lo tanto, la necesidad del patrón singleton . Un AuthService es un gran ejemplo aquí: no desea tener una instancia del servicio con un usuario no autenticado mientras que otra tiene "el mismo" usuario autenticado.
Nuevo en Angular 6, hay una nueva forma de registrar un proveedor como singleton. Dentro del decorador @Injectable () para un servicio, use el atributo proporcionadoIn. Establezca su valor en ''root''. Entonces no necesitará agregarlo a la lista de proveedores del módulo raíz, o en este caso también podría configurarlo en su SharedModule de esta manera:
@Injectable({
providedIn: SharedModule // or ''root'' for singleton
})
export class AuthService {
...
En cuanto a
forRoot
destinado solo a proporcionar servicios únicos, puede "volver a proporcionarlos" explícitamente en
SharedModule
:
@NgModule({})
class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
AuthService,
FeatureModuleA.forRoot().providers,
FeatureModuleB.forRoot().providers,
],
}
}
}
De esta forma, todos los servicios serán proporcionados por el
SharedModule
(no por el submódulo respectivo), pero parece que no importa.
Quizás alguien pueda discutir ...
Tenga en cuenta que
FeatureModuleA
también puede "volver a proporcionar" servicios singleton desde sus submódulos de manera similar.
En general,
forRoot
se usa para agregar servicios de aplicación / singleton.
@NgModule({
providers: [ /* DONT ADD HERE */ ]
})
class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [ AuthService ]
}
}
}
El razonamiento es que si agrega
AuthService
a los
providers
en
@NgModule
, es posible que se cree más de uno si importa
SharedModule
a otros módulos.
No estoy 100% claro sobre si el servicio se crearía cuando
SharedModule
se importara en un módulo cargado con entusiasmo, pero la explicación de que los documentos mencionados se referían a módulos con carga lenta.
Cuando carga un módulo de manera perezosa, se crearán todos los proveedores.
Por esta razón, agregamos un método (por convención)
forRoot
para indicar que el método solo debe llamarse para el módulo raíz (aplicación), mientras que para otro módulo solo debe importarse normalmente
@NgModule({
imports: [SharedModule]
})
class FeatureModule {}
@NgModule({
imports: [SharedModule.forRoot()]
})
class AppModule {}