Ok, me estoy adentrando en la herencia de TypeScript (específicamente en Angular 11), y configuré un BasePageComponent
para proporcionar todas las funciones y servicios necesarios que existen en las páginas. El problema con el que me he encontrado es que ahora mi base se está inflando, porque hay servicios que se usan solo en una o dos páginas, pero para ampliar la base, los hemos incluido en la base.
export class BasePageComponent { constructor( public uiPopupService: UiPopUpService, public loaderService: LoaderService, public questionService: QuestionService, public aBunchOfOthers: OTHERS, public exampleOneOffService: ExampleOneOffService ) {} }
Me doy cuenta de que sería más eficaz repetir todos los servicios inyectados y luego pasarlos todos a BasePageComponent
así:
export class ChildPageComponent extends BasePageComponent { constructor( public uiPopupService: UiPopUpService, public loaderService: LoaderService, public questionService: QuestionService, public aBunchOfOthers: OTHERS, private exampleOneOffService: ExampleOneOffService ) { super(uiPopupService, loaderService, questionService, aBunchOfOthers); } }
Haré lo anterior, si no hay otra manera, pero como se insinuó en el código de muestra, tengo muchos otros microservicios que están incluidos en la base (como 15-20), así que quiero poder para hacer algo como esto, donde solo declaro un servicio adicional y sigo heredando todos los demás de la clase principal, pero no veo la manera de hacerlo.
export class ChildPageComponent extends BasePageComponent { constructor(private otherExampleService: OtherExampleService){ super() }; }
¿Existe este patrón y simplemente no estoy buscando en Google la palabra clave correcta?
Así no es como funciona el DI.
El DI le proporcionará los parámetros de su constructor. No tiene conocimiento de la clase padre.
Las clases principales no obtendrán nada del DI si se llama desde una subclase. En este caso, los parámetros se pasan a través super()
Esto es un poco irónico, está usando la herencia para evitar la inyección de dependencia, cuando en realidad debería usar la inyección de dependencia para evitar la herencia. Si los componentes tienen servicios compartidos, todo lo que necesita hacer es colocar los que necesita en el constructor y listo.
Si tienen funciones compartidas, puede poner las funciones en un servicio. Si tienen variables compartidas, puede usar servicios para pasar datos. El punto es tener componentes como sus propias entidades separadas, por lo que si cambia uno, no afecta a los demás.
Los servicios siguen esta misma filosofía, porque puede cambiar la implementación del servicio, sin tener que tocar ningún archivo que use el servicio. Piense en su diseño, ¿qué sucede si necesita eliminar o agregar un servicio al componente base? Ahora necesita ir y editar todos los demás componentes en todo su proyecto. Y cuando inyecta un servicio en un componente, también crea una instancia de ese servicio. Al inyectar todos sus servicios en cada componente, está creando innumerables instancias de memoria y potencia de procesamiento desperdiciadas. ¿Y realmente ganas algo a cambio?
Lo que estoy tratando de decir es que debe intentar evitar la extensión de componentes. Angular proporciona filosofías de diseño mucho mejores.
Para responder a su pregunta, sí, podría crear un servicio global que importe todos sus otros servicios y luego inyectar ese servicio masivo. Luego podría extender ese servicio e importar aún más. Pero por el amor de todo lo que es sagrado, por favor no lo hagas.
Gracias al comentario de @MikeOne por su enlace a otra respuesta ( Inyectar un servicio manualmente ).
Pude usar Injector.get
para los 15 servicios pequeños que se usan básicamente en todos los componentes secundarios. Luego, para los servicios más grandes y los servicios que solo se usan en algunos componentes secundarios, los inyecté en los componentes relevantes.
Para cualquier otra persona que venga aquí en el futuro: un inconveniente con el que me encontré es que ActivatedRoute
de Angular aparentemente no funciona con Injector.get
(consulte ¿Cómo recuperar un parámetro de ruta usando Injector.get (ActivatedRoute)? ), así que tenía inyectar eso en cada uno de los componentes relevantes, que era la mayoría de ellos, pero aún así es mejor que 16 servicios únicos que se inicializan en cada página.