Simplification de la logique de vue dans Angular

Mar 02 2023
Récemment, j'ai dû implémenter une vue popover avec de nombreuses variantes basées sur des conditions complexes. L'utilisation de ngSwitch, dans ce cas, était impossible, et l'utilisation de ngIf est illisible et détaillée.

Récemment, j'ai dû implémenter une vue popover avec de nombreuses variantes basées sur des conditions complexes. L'utilisation de ngSwitch, dans ce cas, était impossible, et l'utilisation ngIfest illisible et verbeuse.

Voici comment j'ai décidé d'aborder ce problème. La première étape a été de créer une directive nommée TemplateIdDirective:

@Directive({
  selector: 'ng-template[id]',
  standalone: true
})
export class TemplateIdDirective {
  @Input() id: string;
  
  tpl = inject(TemplateRef);
}

<-- trace-information.component.html -->

<div>
  <p>{{ header }}</p>
  <ng-template [ngTemplateOutlet]="body"></ng-template>
</div>

<ng-template id="variation-one">...</ng-template>
<ng-template id="variation-two">...</ng-template>
<ng-template id="variation-three">...</ng-template>
<ng-template id="variation-four">...</ng-template>
<ng-template id="variation-five">...</ng-template>

@Component({
  selector: 'app-trace-information',
  standalone: true,
  imports: [TemplateIdDirective],
  templateUrl: './trace-information.component.html'
})
export class TraceInformationComponent {
  header = '';

  @Input() traceInfo: TraceInfo;
  
  @ViewChildren(TemplateIdDirective) 
  templates: QueryList<TemplateIdDirective>;
  
  private cdr = inject(ChangeDetectorRef);

  ngAfterViewInit() {
    this.resolveView();
  }
 
  private resolveView() {
    // All the complex conditions are defined here.
    // In real life is way more complicated than that.
    // This is only for illustration
    if(...) {
      this.header = '...';
      this.body = this.getTemplate('variation-one');
    } else if(...) {
       if(...) {
         this.header = '...';
         this.body = this.getTemplate('variation-two'); 
       } else {
         this.header = '...';
         this.body = this.getTemplate('variation-three');
       }
    }

    this.cdr.detectChanges();
  }


  private getTemplate(id: string) {
    return this.templates.find((tpl) => tpl.id === id).tpl;
  }
}

Suivez-moi sur Medium ou Twitter pour en savoir plus sur Angular et JS !