gpt4 book ai didi

angular - 如何在 Angular 2 中动态添加和删除表单字段

转载 作者:太空狗 更新时间:2023-10-29 16:46:29 33 4
gpt4 key购买 nike

我正在尝试在用户单击添加按钮时动态添加输入字段,并且对于每个表单字段必须有一个删除按钮,当用户单击必须删除表单字段时,我需要使用 Angular 2 来实现这一点,如我是 Angular 2 的新手,请帮我完成它

我试过的

我创建了一组字段(3 个选择框和 1 个文本框),创建了一个名为添加字段的按钮,但我在 angular 1.x 中尝试过它工作正常,但在 angular 2 中我不知道如何完成它, 这是 link我的全部工作

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: ''
};

最佳答案

这晚了几个月,但我想我会根据 this here tutorial 提供我的解决方案.其要点是,一旦您改变处理表单的方式,管理起来就会容易得多。

首先,使用ReactiveFormsModule代替或补充正常 FormsModule .使用响应式表单,您可以在组件/服务中创建表单,然后将它们插入页面而不是页面生成表单本身。这是更多的代码,但它更易于测试,更灵活,据我所知,制作许多非平凡形式的最佳方法。

从概念上讲,最终结果看起来有点像这样:

  • 你有一个基地FormGroup随随便便 FormControl整个表单所需的实例。例如,在我链接的教程中,假设您需要一个表单,用户可以在其中输入一次姓名,然后输入任意数量的地址。所有一次性字段输入都在此基本表单组中。
  • 里面FormGroup例如会有一个或多个 FormArray实例。 A FormArray基本上是一种将多个控件组合在一起并对其进行迭代的方法。您也可以放多个 FormGroup数组中的实例,并将它们用作嵌套在较大表单中的本质上的“迷你表单”。
  • 通过嵌套多个 FormGroup和/或 FormControl动态中的实例 FormArray ,您可以控制有效性并将表单管理为由几个动态部分组成的一个大的、 react 性的部分。例如,如果你想在允许用户提交之前检查每一个输入是否有效,一个子表单的有效性会“冒泡”到顶级表单,整个表单变得无效,这样很容易管理动态输入。
  • 作为 FormArray本质上,它是一个数组接口(interface)的包装器,但对于表单部分,您可以随时推送、弹出、插入和删除控件,而无需重新创建表单或进行复杂的交互。

  • 如果我链接到的教程失败,这里有一些示例代码,您可以自己实现(我的示例使用 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 .基本模板将子组传递给子组件,然后您可以动态处理整个表单的验证。

    此外,这使得通过有策略地从表单中插入和删除组件来重新排序组件变得微不足道。它适用于(似乎)任意数量的输入,因为它们与名称不冲突(据我所知,模板驱动表单的一个很大缺点)并且您仍然保留了几乎自动验证。这种方法的唯一“缺点”是,除了编写更多代码之外,您还必须重新学习表单的工作原理。但是,随着您的继续,这将为更大和更动态的形式开辟可能性。

    如果您有任何问题或想指出一些错误,请继续。我只是根据我上周自己做的事情输入了上面的代码,名称已更改和其他杂项。属性被遗漏了,但它应该是直截了当的。上面的代码和我自己的代码之间的唯一主要区别是,我将所有的表单构建移到了从组件调用的单独服务中,因此它不那么困惑。

    关于angular - 如何在 Angular 2 中动态添加和删除表单字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38007236/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com