Подтвердить что ты не робот

Как динамически добавлять и удалять поля формы в Angular 2

Я пытаюсь добавить поля ввода динамически, пока пользователь нажимает кнопку добавления, и для каждого поля формы должна быть кнопка удаления, когда пользователь нажимает на то, что поля формы должны быть удалены, мне нужно добиться этого, используя Angular 2, так как я новичок в Angular 2, пожалуйста, помогите мне заполнить его

Что я пробовал

Я создал набор полей (3 select box и 1 текстовое поле), создал кнопку с именем add fields, но я попробовал ее в Angular 1.x, ее отлично работает, но в Angular 2 Не знаю, как это сделать, это ссылка моей полной работы

app/app.component.ts
 import {
    Component
  }
from '@angular/core';
  @Component({
    selector: 'my-app',
    template: `
    <h1>{{title}}</h1>
    <div class="container">
    <button class="btn btn-success bt-sm">add</button>
    <form role="form" calss="form-inline">
    <div class="form-group col-xs-3">
    <label>Select State:</label>
    <select class="form-control" [(ngModel)]="rules.State" id="sel1">
            <option>State1</option>
            <option>State2</option>
            <option>State3</option>
            <option>State4</option>
</select>
     </div>
    <div class="form-group col-xs-3">
<label>Rule:</label>
     <input type="text" data-toggle="modal" data-target="#myModal" class="form-                   control">
    </div>
<div class="form-group col-xs-3">
<label>Pass State :</label>
    <select class="form-control" [(ngModel)]="rules.pass">
    <option>State1</option>
    <option>State2</option>
    <option>State3</option>
    <option>State4</option>
</select>
 </div>
 <div class="form-group col-xs-3">
    <label>Fail State:</label>
        <select class="form-control" [(ngModel)]="rules.fail">
        <option>State1</option>
        <option>State2</option>
        <option>State3</option>
     <option>State4</option>
     </select>
         </div>
    </form>
     </div>
 <div class="modal fade" id="myModal" role="dialog">
      <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                     <button type="button" class="close" data-dismiss="modal">&times    </button>
                    <h4 class="modal-title">Rules Configuration</h4>
                </div>
                <div class="modal-body">
                 <p>Rules</p>
                </div>
                 <div class="modal-footer">
                 <button type="button" class="btn btn-default" data-  dismiss="modal">Close</button>
                </div>
             </div>

                </div>
                 </div>
`
    })
    export class AppComponent {
            title = 'Rule Engine Demo';
          rules: Rules = {
                  State: '',
                  pass: '',
                 fail: ''
                };
4b9b3361

Ответ 1

Это несколько месяцев спустя, но я подумал, что предоставил свое решение на основе этого учебника. Суть его в том, что вам намного легче управлять, как только вы меняете способ приближения к формам.

Сначала используйте ReactiveFormsModule вместо или в дополнение к нормальному FormsModule. С реактивными формами вы создаете свои формы в своих компонентах/сервисах, а затем подключаете их к своей странице, а не страницу, генерирующую форму. Это немного больше кода, но это намного более проверяемо, намного более гибко, и насколько я могу сказать, лучший способ сделать много нетривиальных форм.

Конечный результат будет выглядеть примерно так: концептуально:

  • У вас есть одна база FormGroup с любыми FormControl экземплярами, необходимыми для всей формы. Например, как и в учебнике, к которому я привязался, давайте скажем, что вам нужна форма, в которой пользователь может ввести свое имя один раз, а затем любое количество адресов. Все одноразовые входы поля будут в этой базовой форме.

  • Внутри экземпляра FormGroup будет один или несколько экземпляров FormArray. A FormArray - это в основном способ группировать несколько элементов управления вместе и перебирать их. Вы также можете поместить несколько экземпляров FormGroup в свой массив и использовать их как по существу "мини-формы", вложенные в вашу большую форму.

  • Встраивая несколько экземпляров FormGroup и/или FormControl в динамический FormArray, вы можете управлять достоверностью и управлять формой как одной, большой реактивной частью, состоящей из нескольких динамических частей. Например, если вы хотите проверить, действителен ли каждый отдельный вход, прежде чем разрешить пользователю отправлять данные, действительность одной подформы будет "пузыриться" до формы верхнего уровня, а вся форма становится недействительной, что упрощает управлять динамическими входами.

  • Поскольку FormArray является, по существу, оберткой вокруг интерфейса массива, но для частей формы, вы можете в любое время удалять, удалять, вставлять и удалять элементы управления без повторного создания формы или выполнения сложных взаимодействий.

В случае, если учебник, с которым я связан, идет вниз, вот пример кода, который вы можете реализовать самостоятельно (мои примеры используют TypeScript), которые иллюстрируют основные идеи:

Код базового компонента:

import { Component, Input, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'my-form-component',
  templateUrl: './my-form.component.html'
})
export class MyFormComponent implements OnInit {
    @Input() inputArray: ArrayType[];
    myForm: FormGroup;

    constructor(private fb: FormBuilder) {}
    ngOnInit(): void {
        let newForm = this.fb.group({
            appearsOnce: ['InitialValue', [Validators.required, Validators.maxLength(25)]],
            formArray: this.fb.array([])
        });

        const arrayControl = <FormArray>newForm.controls['formArray'];
        this.inputArray.forEach(item => {
            let newGroup = this.fb.group({
                itemPropertyOne: ['InitialValue', [Validators.required]],
                itemPropertyTwo: ['InitialValue', [Validators.minLength(5), Validators.maxLength(20)]]
            });
            arrayControl.push(newGroup);
        });

        this.myForm = newForm;
    }
    addInput(): void {
        const arrayControl = <FormArray>this.myForm.controls['formArray'];
        let newGroup = this.fb.group({

            /* Fill this in identically to the one in ngOnInit */

        });
        arrayControl.push(newGroup);
    }
    delInput(index: number): void {
        const arrayControl = <FormArray>this.myForm.controls['formArray'];
        arrayControl.removeAt(index);
    }
    onSubmit(): void {
        console.log(this.myForm.value);
        // Your form value is outputted as a JavaScript object.
        // Parse it as JSON or take the values necessary to use as you like
    }
}

Подкомпонентный код: (по одному для каждого нового поля ввода, чтобы сохранить чистоту)

import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
    selector: 'my-form-sub-component',
    templateUrl: './my-form-sub-component.html'
})
export class MyFormSubComponent {
    @Input() myForm: FormGroup; // This component is passed a FormGroup from the base component template
}

Базовый компонент HTML

<form [formGroup]="myForm" (ngSubmit)="onSubmit()" novalidate>
    <label>Appears Once:</label>
    <input type="text" formControlName="appearsOnce" />

    <div formArrayName="formArray">
        <div *ngFor="let control of myForm.controls['formArray'].controls; let i = index">
            <button type="button" (click)="delInput(i)">Delete</button>
            <my-form-sub-component [myForm]="myForm.controls.formArray.controls[i]"></my-form-sub-component>
        </div>
    </div>
    <button type="button" (click)="addInput()">Add</button>
    <button type="submit" [disabled]="!myForm.valid">Save</button>
</form>

Подкомпонентный HTML

<div [formGroup]="form">
    <label>Property One: </label>
    <input type="text" formControlName="propertyOne"/>

    <label >Property Two: </label>
    <input type="number" formControlName="propertyTwo"/>
</div>

В приведенном выше коде у меня в основном есть компонент, который представляет базу формы, а затем каждый подкомпонент управляет собственным экземпляром FormGroup внутри FormArray, расположенным внутри базы FormGroup. Базовый шаблон проходит по подгруппе в подкомпонент, а затем вы можете обрабатывать валидацию для всей формы динамически.

Кроме того, это делает тривиальным переупорядочить компонент, стратегически вставляя и удаляя их из формы. Он работает с (по-видимому) с любым количеством входов, поскольку они не конфликтуют с именами (большой недостаток форм, управляемых шаблонами, насколько мне известно), и вы по-прежнему сохраняете почти автоматическую проверку. Единственным "недостатком" этого подхода является, помимо написания немного больше кода, вам нужно заново изучить, как работают формы. Тем не менее, это откроет возможности для гораздо более крупных и динамичных форм, когда вы продолжаете.

Если у вас есть какие-либо вопросы или вы хотите указать некоторые ошибки, продолжайте. Я только что набрал вышеуказанный код, основываясь на том, что я сделал сам на прошлой неделе, с измененными именами и другими разным. свойства оставлены, но это должно быть просто. Единственное существенное различие между приведенным выше кодом и моей собственностью заключается в том, что я переместил все формы в отдельную службу, вызванную из компонента, так что она немного менее беспорядочна.

Ответ 2

addAccordian (тип, данные) {console.log (тип, данные);

let form = this.form;

if (!form.controls[type]) {
  let ownerAccordian = new FormArray([]);
  const group = new FormGroup({});
  ownerAccordian.push(
    this.applicationService.createControlWithGroup(data, group)
  );
  form.controls[type] = ownerAccordian;
} else {
  const group = new FormGroup({});
  (<FormArray>form.get(type)).push(
    this.applicationService.createControlWithGroup(data, group)
  );
}
console.log(this.form);
let form = this.form;

if (!form.controls[type]) {
  let ownerAccordian = new FormArray([]);
  const group = new FormGroup({});
  ownerAccordian.push(
    this.applicationService.createControlWithGroup(data, group)
  );
  form.controls[type] = ownerAccordian;
} else {
  const group = new FormGroup({});
  (<FormArray>form.get(type)).push(
    this.applicationService.createControlWithGroup(data, group)
  );
}
console.log(this.form);

} }