Angular: варианты рефакторинга оператора switch для компонентов без изменения результирующего DOM - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь заменить различные случаи оператора switch на компоненты без изменения результирующего дерева DOM.

Пример

Я сделал пример для stackblitz .

В качестве основы я использовал пример Dynami c Forms из руководства angular .io.

Компонент, который я хочу реорганизовать, - DynamicFormQuestion . Цель состоит в том, чтобы ввести новый компонент для каждого элемента управления controlType ( QuestionDropdownComponent , QuestionTextBoxComponent ) без изменений в результирующем DOM. DynamicFormQuestionComponent все еще следует использовать в качестве компонента для вопроса любого типа.

Оригинал dynamici c -form-question.component. html:

<div [formGroup]="form">
  <label [attr.for]="question.key">{{question.label}}</label>

  <div [ngSwitch]="question.controlType">

    <input *ngSwitchCase="'textbox'" [formControlName]="question.key"
            [id]="question.key" [type]="question.type">

    <select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
      <option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
    </select>

  </div>

  <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

Новые шаблоны

dynamici c -form-question.component. html:

<ng-container [ngSwitch]="question.controlType">
    <app-question-textbox *ngSwitchCase="'textbox'" [question]="question" [form]="form"></app-question-textbox>
    <app-question-dropdown *ngSwitchCase="'dropdown'" [question]="question" [form]="form"></app-question-dropdown>
</ng-container>

question-textbox.component. html:

<div [formGroup]="form">
  <label [attr.for]="question.key">{{question.label}}</label>
  <input [formControlName]="question.key" [id]="question.key" [type]="question.type">
  <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

question-dropdown.component. html:

<div [formGroup]="form">
    <label [attr.for]="question.key">{{question.label}}</label>
    <select [id]="question.key" [formControlName]="question.key">
      <option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
  </select>
    <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

Этот пример работает, но результирующее дерево DOM содержит нежелательные элементы <app-question-textbox> и <app-question-dropdown>.

Как лучше всего избавиться от него?

1 Ответ

0 голосов
/ 09 апреля 2020

Это можно сделать с помощью селектора атрибута , но требуется один div. Можно сделать так, как показано ниже:

<ng-container [ngSwitch]="question.controlType">
    <div app-question-textbox *ngSwitchCase="'textbox'" [question]="question" [form]="form"></div>
    <div app-question-dropdown *ngSwitchCase="'dropdown'" [question]="question" [form]="form"></div>
</ng-container>

Остальные будут такими же.

...