Search code examples
angularchildren

ContentChild by extended abstract class


I have two different components that extend a common one.

AComponent extends BaseComponent {}
BComponent extends BaseComponent {}

There is a third component that has ng-content.

<wrapper>
  <a-component></a-component>
  <b-component></b-component>
</wrapper>

Unfortunately those component aren't visible in below scenario.

WrapperComponent {
  @ContentChildren(BaseComponent) components;
}

I don't want to create ContentChild with specific types (Acomponent, BComponnet).


Solution

  • you can use Alias providers as a workaround.

    Define your components as follows;

    @Component({
      selector: 'a-component',
      templateUrl: './a.component.html',
      styleUrls: ['./a.component.css'],
      providers: [{ provide: BaseComponent, useExisting: AComponent }]
    })
    export class AComponent extends BaseComponent implements OnInit {
      constructor() {
        super();
        console.log("a created.");
      }
    
      ngOnInit() {}
    }
    

    and

    @Component({
      selector: 'b-component',
      templateUrl: './b.component.html',
      styleUrls: ['./b.component.css'],
      providers: [{ provide: BaseComponent, useExisting: BComponent }]
    })
    export class BComponent extends BaseComponent implements OnInit {
      constructor() {
        super();
        console.log("b created.");
      }
    
      ngOnInit() {}
    }
    

    where BaseComponent is

    export abstract class BaseComponent {}
    

    use it in the WrapperComponent as follows

    @Component({
      selector: 'wrapper',
      templateUrl: './wrapper.component.html',
      styleUrls: ['./wrapper.component.css']
    })
    export class WrapperComponent implements OnInit, AfterContentInit {
      @ContentChildren(BaseComponent) components;
    
      constructor() { }
    
      ngOnInit() { }
    
      ngAfterContentInit() {
        console.log("components: ", this.components.length);
      }
    }
    

    here is a working demo https://stackblitz.com/edit/angular-ynqhwj