Crocsx
Crocsx

Reputation: 7609

different type of ContentChildren

I have a component (radio-group) that group some other component (radio-button)

To get all the button contained in the group I do this :

  @ContentChildren(RadioButtonComponent, { descendants: true })
  radios: QueryList<RadioButtonComponent>;

with radioButton being a normal angular component

@Component({
  selector: 'app-radio-button',
  templateUrl: './radio-button.component.html',
  styleUrls: ['./radio-button.component.scss'],
})
export class RadioButtonComponent implements Radio {
  @Input() value: any;
  @Input() disabled: boolean;
  // etc...
}

now, I want to create a new type of radio button with a different template, but the same code as radioButton for ex

@Component({
  selector: 'app-radio-tiled-button',
  templateUrl: './radio-tiled-button.component.html',
  styleUrls: ['./radio-tiled-button.component.scss'],
})
export class RadioTiledButtonComponent implements Radio {
  @Input() value: any;
  @Input() image: string;
  @Input() name: string;
  @Input() disabled: boolean;
  // etc...
}

The problem is, although they share the same public method and interface, I do not find a way to recover all of them inside the ContentChildren

  @ContentChildren(RadioButtonComponent, { descendants: true })
  radios: QueryList<RadioButtonComponent>;

how can I do that ?

I have seen this post => ContentChildren with multiple content types

but it doesn't ANSWER my question because directive do not have template, so it's a different problem.

Upvotes: 1

Views: 715

Answers (1)

Zonaib
Zonaib

Reputation: 341

If they share the same public method and interfaces, you can always do a contentchildren using an abstract class.

In both of your components metadata, do the following:

@Component({
  selector: 'ComponentA',
  provider: [{ provide: IParentComponent, useExisting: forwardRef(() => ComponentA) }],
  template: '',
})
export class ComponentA implements IParentComponent { 
  getSelectedValue(): { return 1; }
}

@Component({
  selector: 'ComponentB',
  provider: [{ provide: IParentComponent, useExisting: forwardRef(() => ComponentB) }],
  template: '',
})
export class ComponentB implements IParentComponent { 
  getSelectedValue(): { return 1; }
}

// some example methods
export abstract class IParentComponent {
   abstract getSelectedValue(): number;
}

Followed by: @ContentChildren(IParentComponent , { descendants: true }) radios: QueryList;

This will give you a handle to both of your components.

Upvotes: 2

Related Questions