Đơn giản hóa View Logic trong Angular

Mar 02 2023
Gần đây, tôi đã phải triển khai chế độ xem popover với nhiều biến thể dựa trên các điều kiện phức tạp. Trong trường hợp này, sử dụng ngSwitch là không thể và sử dụng ngIf thì không thể đọc được và dài dòng.

Gần đây, tôi đã phải triển khai chế độ xem popover với nhiều biến thể dựa trên các điều kiện phức tạp. Việc sử dụng ngSwitch, trong trường hợp này, là không thể và việc sử dụng ngIfkhông thể đọc được và dài dòng.

Đây là cách tôi quyết định tiếp cận vấn đề này. Bước đầu tiên là tạo một lệnh có tên 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;
  }
}

Theo dõi tôi trên Medium hoặc Twitter để đọc thêm về Angular và JS!