Вложенные поля угловой динамической формы

С помощью https://angular.io/guide/dynamic-form я создание динамической формы, в которой мне нужно сначала отобразить два поля.

  new TextboxQuestion({
    key: 'firstName',
    label: 'First name',
    value: '',
    required: true,
    order: 1
  }),

  new TextboxQuestion({
    key: 'lastName',
    label: 'Last name',
    value: '',
    required: true,
    order: 2
  }),

Эти два поля должны быть сначала загружены.

После этого у меня будут две кнопки add and remove.

  <button (click)="addNew()"> Add </button> &nbsp;&nbsp;&nbsp;
  <button (click)="removeNew()"> Remove </button> <br><br>

Нажав на кнопку «Добавить», мне нужно отобразить следующие два поля (следующие поля),

  new TextboxQuestion({
    key: 'emailAddress',
    label: 'Email',
    type: 'email',
    order: 3
  }),

  new DropdownQuestion({
    key: 'brave',
    label: 'Bravery Rating',
    options: [
      {key: 'solid',  value: 'Solid'},
      {key: 'great',  value: 'Great'},
      {key: 'good',   value: 'Good'},
      {key: 'unproven', value: 'Unproven'}
    ],
    order: 4
  })

Порядок 1 и 2 в исходном состоянии, и после нажатия кнопки «Добавить» должны появиться следующие два порядка 3 и 4.

KIndly помогите мне добиться результата добавления дочерних полей при нажатии кнопки добавления.

Рабочий stackblitz, который отображает все сразу, https://stackblitz.com/edit/angular-x4a5b6


person Maniraj Murugan    schedule 01.11.2018    source источник


Ответы (2)


Реализация динамической формы с помощью formArray.

Что ж, дело обстоит сложнее. Я делаю stackblik, см. demo < / а>

Я попытаюсь объяснить, как расширяет https://angular.io/guide/dynamic-form, чтобы разрешить Form Array.

Первое, что нам нужно сделать, это создать вопрос нового типа, questionArray.

import { QuestionBase } from './question-base';

export class ArrayQuestion extends QuestionBase<string> {
  controlType = 'array';
  type: any;

  constructor(options: {} = {}) {
    super(options);
  }
}

Мы должны изменить базу вопросов, чтобы добавить новое свойство «дети».

export class QuestionBase<T> {
  value: T;
  ...
  children:any[];

  constructor(options: {
      value?: T,
      ...
      children?:any
    } = {}) {
    this.value = options.value;
    ...
    this.children=options.children || null;
  }
}

Добавить изменение службы управления вопросами, чтобы разрешить управление массивами форм

toFormGroup(questions: QuestionBase<any>[]) {
    let group: any = {};

    questions.forEach(question => {
      //If the control type is "array" we create a FormArray
      if (question.controlType=="array") {
         group[question.key]=new FormArray([]);
      }
      else {
        group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
          : new FormControl(question.value || '');
      }
    });
    return new FormGroup(group);
  }

Что ж, мы преобразуем компонент dynamic-form.com, чтобы показать FormArray

<div *ngFor="let question of questions" class="form-row">
    <ng-container *ngIf="question.children">
        <div [formArrayName]="question.key">
            <div *ngFor="let item of form.get(question.key).controls; let i=index" [formGroupName]="i">
                <div *ngFor="let item of question.children">
                    <app-question [question]="item" [form]="form.get(question.key).at(i)"></app-question>
                </div>
            </div>
        </div>
    </ng-container>
    <ng-container *ngIf="!question.children">
        <app-question [question]="question" [form]="form"></app-question>

    </ng-container>
</div>

И это просто так. Ну как увеличивать и уменьшать formArrays? У нас две кнопки

  <button (click)="addControls('myArray')"> Add </button>
  <button (click)="removeControls('myArray')"> Remove </button> <br><br>

И две функции addControls и removeControls

  addControls(control: string) {
    let question: any = this.questions.find(q => q.key == control);
    let children = question ? question.children : null;
    if (children)
      (this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))
  }
  removeControls(control: string){
    let array=this.form.get(control) as FormArray;
    array.removeAt(array.length-1);
  }

Обновить Я забыл добавить и пример вопросов:

let questions: QuestionBase<any>[] = [

      new TextboxQuestion({
        key: 'firstName',
        label: 'First name',
        value: '',
        required: true,
        order: 1
      }),

      new TextboxQuestion({
        key: 'lastName',
        label: 'Last name',
        value: '',
        required: true,
        order: 2
      }),
      new ArrayQuestion({
        key: 'myArray',
        value: '',
        order: 3,
        children: [
          new TextboxQuestion({
            key: 'emailAddress',
            label: 'Email',
            type: 'email',
            order: 3
          }),
          new DropdownQuestion({
            key: 'brave',
            label: 'Bravery Rating',
            options: [
              { key: 'solid', value: 'Solid' },
              { key: 'great', value: 'Great' },
              { key: 'good', value: 'Good' },
              { key: 'unproven', value: 'Unproven' }
            ],
            order: 4
          })
        ]
      })
    ];
person Eliseo    schedule 01.11.2018
comment
Eliseo Большое спасибо .. Я надеюсь, что после просмотра stackblitz у меня все будет хорошо .. Если какие-то сомнения вернутся к вам .. - person Maniraj Murugan; 01.11.2018
comment
Элисео, я разместил еще один вопрос stackoverflow.com/questions/53113962/, чтобы загрузить данные из JSON для входов. Это только ваше решение, но только данные, которые мне нужно предоставить как JSON для каждого входа. Если вы отсылаете вопрос, получит хорошее понимание .. Вы можете мне помочь ?? - person Maniraj Murugan; 02.11.2018
comment
Привет, Элисео! Вот еще один новый вопрос для вас stackoverflow.com/questions/53220425/ для исправления данных в этих элементах формы во время редактирования .. - person Maniraj Murugan; 09.11.2018

Единственное, что вам нужно, это разбить свои вопросы на страницы с помощью фрагмента и переменной page.

Это:

  //add a variable "page" in your dinamic-form.component.ts
  page:number=0;

и

  //in your dinamic-form.component.html, change the *ngFor like
  <form (ngSubmit)="onSubmit()" [formGroup]="form">
    <div *ngFor="let question of questions.slice(page*2,(page+1)*2)" class="form-row">
      <app-question [question]="question" [form]="form"></app-question>
    </div>
   ....
  </form>

Тогда ваша кнопка добавления может быть похожей на

  <button (click)="page=page+1"> Add </button>
person Eliseo    schedule 01.11.2018
comment
Спасибо за вашу помощь. Пожалуйста, предоставьте stackblitz, который мне поможет. Я реализовал ваш код, но не смог получить никаких входных данных stackblitz.com/edit/angular-x4a5b6 - person Maniraj Murugan; 01.11.2018
comment
Вы забыли добавить страницу свойств. В вашем dinamic-form.component.ts вам нужно добавить page: number = 0 сразу после инструкции: payLoad = '' - person Eliseo; 01.11.2018
comment
Если я нажму кнопку «Добавить», то старые текстовые поля ввода будут скрыты, и появятся следующие два. Мне нужно отобразить первые два в начале, и при нажатии кнопки «Добавить» следующие два должны появиться и снова щелкнуть «Добавить добавленное». два текстовых поля (порядок 3 и 4) должны быть привязаны при каждом нажатии на кнопку добавления .. Мне нужно показать оба порядка (1 и 2) при нажатии кнопки добавления .. Я надеюсь, что вы на полпути, чтобы помочь мне .. Пожалуйста Элисео, я прошу вас помочь мне, что было бы гораздо более заметно .. - person Maniraj Murugan; 01.11.2018
comment
просто замените фрагмент на фрагмент (0, (page + 1) * 2). Идея в том, что вы не показываете все вопросы, которые вам нужны, в каждый момент. Я полагаю, вы хотите показывать только два за раз - person Eliseo; 01.11.2018
comment
Только последний вопрос для вас в последнем .. При повторном нажатии на кнопку добавления я должен получать добавление порядка (3 и 4) при каждом нажатии кнопки добавления .. Ты был единственным, кто мне очень помог в этом .. Любезный ответ для только этот .. Я обязательно приму ваш ответ, пожалуйста .. - person Maniraj Murugan; 01.11.2018
comment
Элисео там ?? Надеюсь, вы хорошо понимаете мое требование.У меня есть форма, в которой первые два поля будут статичными, всегда при заполнении первых двух будет кнопка добавления при нажатии, следующие два будут отображаться, но после каждого добавления щелкните эти два нужно добавлять по одному каждый раз (это будет массив объектов) .. Атласт, сохраняя форму, все должно быть сохранено .. Пожалуйста, извините меня за то, что спрашиваю снова и снова, так как вы эксперт в angular, вы можете мне помочь из .. Застрял в нем надолго .. - person Maniraj Murugan; 01.11.2018
comment
@Mani, дела обстоят посложнее. Я думаю, вы хотите создать массив формы. Создаю новый ответ. Я надеюсь это поможет - person Eliseo; 01.11.2018
comment
Элисео, нет слов, чтобы выразить тебе благодарность .. Ты молодец .. Я действительно хочу выразить тебе особую благодарность за то, что ты потратил свое драгоценное и драгоценное время на то, чтобы дать мне решение .. Большое спасибо .. - person Maniraj Murugan; 01.11.2018
comment
Пожалуйста, было приятно иметь возможность помочь вам - person Eliseo; 01.11.2018