0

Let's say I have the following files

blog.abstract.ts

import { Component, ElementRef } from '@angular/core';
import { ItemService } from 'services/item/item.service';
import { Router } from '@angular/router';
import { ModalService } from 'services/modal/modal.service';

export class AbstractBlog {
  constructor(protected modalService: ModalService, protected router: Router, protected itemService: ItemService) { }
  // use services
}

blog1.component.ts

import { Component, ElementRef } from '@angular/core';
import { ItemService } from 'services/item/item.service';
import { Router } from '@angular/router';
import { ModalService } from 'services/modal/modal.service';

@Component({
  selector: 'app-blog-1',
  templateUrl: 'blog-1.html',
})
export class Blog1Component extends AbstractBlog {
  constructor(private _elementRef: ElementRef, modalService: ModalService, router: Router, itemService: ItemService) {
    super(modalService, router, itemService);
  }
  // use services & _elementRef
}

blog2.component.ts

import { Component, ElementRef } from '@angular/core';
import { ItemService } from 'services/item/item.service';
import { Router } from '@angular/router';
import { ModalService } from 'services/modal/modal.service';

@Component({
  selector: 'app-blog-2',
  templateUrl: 'blog-2.html',
})
export class Blog2Component extends AbstractBlog{
  constructor(modalService: ModalService, router: Router, itemService: ItemService) {
    super(modalService, router, itemService);
  }
  // use services
}

I would like to simplify the constructor and avoid importing every services & use the super(....) method each time I need a new BlogComponent.
Let's say that there is hundred of BlogComponent, and each of these are in different folders.
For each of these modules I need to extends AbstractBlog, import services and call the super method with the same parameters.
Now if I want to add another service in the constructor of AbstractBlog I would have to update a hundred files to match the constructor.
Is there a better way to handle this case ?

melkir
  • 405
  • 1
  • 5
  • 22

1 Answers1

1

Due to how inheritance currently works in injectable classes in Angular, DI annotations are inherited from injectable parent class (the one that has Injectable, Component, Directive, ... decorator).

If new dependencies have to be added to child constructor, constructor signature should be repeated entirely, it also pass the dependencies to parent constructor with super(...) (like it is done in original code). Otherwise constructor can be omitted to be inherited from parent class.

It depends on how big is the difference between dependency sets in child classes. If it isn't significant, parent class can have extra dependency or two if it helps to keep child classes DRY:

@Injectable()
export class AbstractBlog {
  constructor(
    protected elementRef: ElementRef, // used only by BlogComponent 
    protected modalService: ModalService,
    protected router: Router,
    protected itemService: ItemService
 ) { }
}

export class BlogComponent extends AbstractBlog {
  // use services
}

export class Blog2Component extends AbstractBlog {
  // use services
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565