I am creating an Angular2 application in Typescript and would like to use the class system functionality (read: class inheritance) offered by Typescript. However, it seems that Angular2 does not play well with derived classes. I am looking for some help with my application.
The problem I am facing is that I have a base class and output some child classes. When I create my component tree, I would like to have access to the parent / child components of the components (this is good anyway). As far as I understand, Angular2 offers two options:
- Insert parent element in child component
- Use ContentChildren (or ViewChildren) to access the children of the component.
Both work fine if you know the type of the class you're working with (ChildComponent), but don't seem to work when you try to use the base class of these components (BaseComponent) as a selector.
To visualize it in some code (see this Plunker for a live demo), I have an application component / class as follows:
@Component({ selector: 'my-app', template: `<parent-comp> <child-comp1></child-comp1> <child-comp1></child-comp1> <child-comp2></child-comp2> </parent-comp>`, directives: [ParentComponent, ChildComponent1, ChildComponent2] }) export class MyApplication { }
The base class and child classes are defined as:
export class BaseComponent { // Interesting stuff here } @Component({ selector: 'child-comp2', template: '<div>child component #2</div>' }) export class ChildComponent2 extends BaseComponent { } @Component({ selector: 'child-comp1', template: '<div>child component #1</div>' }) export class ChildComponent1 extends BaseComponent { }
And the parent class has its own logic for counting its children.
@Component({ selector: 'parent-comp', template: `<div>Hello World</div> <p>Number of Child Component 1 items: {{numComp1}} <p>Number of Child Component 2 items: {{numComp2}} <p>Number of Base Component items: {{numBase}} <p><ng-content></ng-content> ` }) export class ParentComponent implements AfterContentChecked { @ContentChildren(ChildComponent1) contentChild1: QueryList<ChildComponent1> @ContentChildren(ChildComponent2) contentChild2: QueryList<ChildComponent2> @ContentChildren(BaseComponent) contentBase: QueryList<BaseComponent> public numComp1:number public numComp2:number public numBase:number ngAfterContentChecked() { this.numComp1 = this.contentChild1.length this.numComp2 = this.contentChild2.length this.numBase = this.contentBase.length }
(Again, you can see the live demo here )
The output for the first two counters will be as expected. There are 2 ChildComponent1 and 1 ChildComponent2 children. Unfortunately, the BaseComponent counter does not display the sum of these counters, but displays 0. It does not find the BaseComponent class in the child classes.
The same thing happens when a ParentComponent is also distributed from BaseComponent, and you want to embed it in a ChildComponent. An injector will require a specific type of ParentComponent and cannot work with a base class.
Any tips on how to work with derived classes in Angular2? Am I missing something or trying to do something impossible?