Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular circular dependency with "russian dolls" components

We have built a generic master-detail component that will render a specific detail component based on a @Input EntityType property that it gets provided with. In the master detail component template, we call a wrapper/factory component that will render the appropriate detail component based on entityType:

@Component({
  selector: 'master-detail',
  template: `
    <div>
      <grid></grid>
      <detail-wrapper> [entityType]=entityType></detail-wrapper>
    </div>
  `,
})
export class MasterDetailComponent {
  @Input() entityType: string ;
  ...
}

@Component({
  selector: 'detail-wrapper',
  template: `
    <ng-container [ngSwitch]="entityType">
      <comp-a *ngSwitchCase="'A'"></comp-a>
      <comp-b *ngSwitchCase="'B'""></comp-b>
      <comp-default *ngSwitchDefault></comp-default>
    </ng-container>
  `,
})
export class DetailWrapperComponent {
  @Input() entityType: string ;
  ...
}

The detail component can itself contain another master-detail component (like russian dolls). However when this happens, my code won't run because of circular dependency:

master-detail -> detail-wrapper -> compA -> master-detail

I know I could break the circular dependency this by creating duplicates for each level using inheritance :

export class MasterDetailLevel2Component extends MasterDetailComponent {...}
export class CompALevel2Component extends CompAComponent {...}

But that really doesn't look like a proper solution and involves creating classes for each recursion level.

Another possibility I see would be to use ComponentFactoryResolver instead of DetailWrapperComponent. The MasterDetailComponent would then be provided with a component factory interface (therefore removing the linking between the concrete implementation). But with this solution, I'm loosing template bindings.

Is there a better way to get out of this ?

like image 253
Seb_Lz Avatar asked Mar 27 '26 07:03

Seb_Lz


1 Answers

The best solution I've found is to use a @ContentChild in my master-detail component and let it be injected with a detail template coming from a parent component. This way I get rid of circular dependency and also make my component more flexible. Here is a very good article about this:

https://blog.jonrshar.pe/2017/May/29/angular-ng-template-outlet.html

like image 73
Seb_Lz Avatar answered Mar 30 '26 00:03

Seb_Lz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!