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

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

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

Я создал набор полей (3 поля выбора и 1 текстовое поле), создал кнопку с именем «Добавить поля», но я попробовал ее в угловом 1.x, он работает нормально, но в угловом 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: ''
                };
 Ankit Singh28 июн. 2016 г., 12:14
Вы имеете в виду инъекцию скриптов с использованием[innerHTML] не работает? Это потому, что angular не позволяет вводить сценарии таким образом
 balajivaishnav28 июн. 2016 г., 12:32
затем, где я могу загрузить теги сценария, если я загружаю в index.html, получаю ошибку как неопределенный тип, если мне нужно использовать сценарий внутри шаблона, любая идея, у вас есть
 balajivaishnav28 июн. 2016 г., 11:48
@A_Singh у вас есть идея, почему Angular 2 не загружает шаблон HTML-код внутренних сценариев
 Ankit Singh24 июн. 2016 г., 13:22
Ты можешь использоватьControlGroup для достижения этой целиstackoverflow.com/questions/36627573/...
 balajivaishnav28 июн. 2016 г., 12:19
нет тегов сценария, вы когда-либо использовали конструктор запросов jquery? ..
 Ankit Singh28 июн. 2016 г., 12:22
query builder ? Нет, но это происходит также потому, что angular не допускает никаких скриптов в шаблонах. увидетьЭта проблема

Ответы на вопрос(1)

Решение Вопроса

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

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

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

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

Внутри этогоFormGroup экземпляр будет один или несколькоFormArray экземпляров.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, Базовый шаблон проходит по подгруппе к подкомпоненту, и затем вы можете динамически обрабатывать проверку всей формы.

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

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

 elporfirio12 сент. 2017 г., 23:22
Как реализовать ngModel в этой форме?
 Runali09 февр. 2018 г., 07:12
да, вышеприведенный подход очень хорош для меня, но я не понимаю, как применить пользовательскую директиву к вышеуказанной вещи.
 Faradox14 окт. 2018 г., 17:40
Вы сохранили мою дату
 Ryan Peters11 нояб. 2017 г., 05:59
@elporfirio Вы не используете ngModel с этими формами. ngModel используется в основном при работе с двусторонним связыванием данных с объектом JavaScript. Эти реактивные формы, по сути, являются собственными объектами с различными полезными полями и свойствами, такими как проверка. Вместо этого вы получаете свойство ".value" из формы, и это набор ваших результатов. Вы можете манипулировать этим любым способом и сопоставить его с любыми имеющимися у вас классами или интерфейсами.
 Anjana Silva13 янв. 2019 г., 15:51
@Faradox: Вы имеете в виду «день», не так ли? ;)

Ваш ответ на вопрос