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

2023-11-29

我试图在用户单击添加按钮时动态添加输入字段,并且对于每个表单字段必须有一个删除按钮,当用户单击必须删除表单字段时,我需要使用 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: ''
                };

这晚了几个月,但我想我会根据以下内容提供我的解决方案这里的教程。其要点是,一旦改变处理表单的方式,管理就会容易得多。

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

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

  • 你有一个基地FormGroup与任何FormControl整个表格所需的实例。例如,正如我链接到的教程中所示,假设您想要一个表单,用户可以在其中输入一次姓名,然后输入任意数量的地址。所有一次性字段输入都将位于该基本表单组中。

  • 里面那个FormGroup实例将有一个或多个FormArray实例。 AFormArray基本上是一种将多个控件组合在一起并迭代它们的方法。也可以放多个FormGroup数组中的实例,并将它们用作本质上嵌套在较大表单中的“迷你表单”。

  • 通过嵌套多个FormGroup and/or FormControl动态中的实例FormArray,您可以控制有效性并将表单作为由多个动态部分组成的一个大的反应性部分进行管理。例如,如果您想在允许用户提交之前检查每个输入是否有效,则一个子表单的有效性将“冒泡”到顶级表单,整个表单将变得无效,从而很容易管理动态输入。

  • As a 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。基本模板将子组传递到子组件,然后您可以动态处理整个表单的验证。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Angular 2 中动态添加和删除表单字段 的相关文章

随机推荐

  • Vue.js项目中添加Tailwind.css后,某些类没有效果

    我正在尝试将 Tailwind css 添加到 Vue js 项目中 有很多关于如何执行此操作的资源 其中大多数都遵循与这个视频 为了确保我处于与视频中相同的条件 我从头开始创建了一个 Vue 应用程序 使用vue cli使用默认预设 完成
  • 使用脚本在 Powershell 命令提示符中填写多个答案

    我正在尝试使用 Powershell 脚本自动填写提示的答案 提示问题如下所示 这些问题由 cmd 文件一个接一个地生成 这意味着输入不会返回到 Powershell 输入 我找到了很多答案来一次回答一个问题或多个是 否问题 但还没有这样的
  • .NET WebAPI集中授权

    在 NET WebAPI 中 我创建了一种将所有授权规则放在一个中央位置的方法 而不是分散在各个控制器中 我很好奇为什么这种集中化没有更频繁地进行 是否有影响 安全问题 我当前的方法是在 App Start 期间创建一个字典 其中包含我的所
  • 如何在我的应用程序中使用密码锁定场景?

    实际上 我构建了一个包含本地身份验证的应用程序 到目前为止我的代码 func authenticateUser let authenticationContext LAContext var error NSError let reason
  • 类中函数原型中的运算符 & 和 *

    我在这样的课程中遇到问题 class Sprite bool checkCollision Sprite spr 所以 如果我有这门课 我可以这样做 ball checkCollision bar1 但如果我将课程更改为 class Spr
  • 用于解压缩文件的 VBA 脚本 - 只是创建空文件夹

    我正在使用 Ron 的代码 http www rondebruin nl win s7 win002 htm 理论上可以将一堆 zip 文件解压到一个文件夹中 我相信下面的代码获取 下载 目录中的每个 zip 文件 使用 zip 文件的名称
  • 如何用selenium继续填充下一页的数据?

    我想通过以下方式登录Selenium 该过程分为2页 email 密码 现在我可以在第一页输入密钥 然后我应该进入下一页 输入密码并单击提交密钥 但是 如果我只在一个类中添加4个按键代码 则无法完成第二页按键输入 密码和提交 我猜想第一页按
  • 为什么Multiprocessing的Lock不会阻止其他进程使用对象?

    以下代码是一家商店的代码 该商店有 5 件商品 三个顾客各需要一件商品 import multiprocessing as mp class Shop def init self stock 5 self stock stock def g
  • 在映射时使用 adf 管道参数作为源到接收器列

    我有一个具有复制活动的 ADF 管道 我正在将数据从 Blob 存储 CSV 文件复制到 SQL 数据库 这按预期工作 我需要映射 CSV 文件的名称 这来自管道参数 并将其保存在目标表中 我想知道是否有办法将参数映射到目标列 列名不能直接
  • 在自定义控制器工厂中进行通用授权的良好做法?

    我的控制器共享一个客户端 ID 路线 clients clientId controller action id 示例网址 clients 1 orders details 1 clients 2 children index client
  • 通过堆栈进行 32 位扩展乘法

    这是我一直用来实现两个 32 位数字的扩展乘法的代码 有没有办法通过创建子程序并通过参数传递使用堆栈来实现类似的逻辑 使用 MUL 指令还是不使用 MUL 指令 有人可以帮忙吗 org 0x0100 jmp start multiplica
  • 迁移到 androidx 后,膨胀类 androidx.constraintlayout.ConstraintLayout 时出错

    我刚刚通过 Android Studio 菜单选项迁移到 androidxRefactor gt 重构为 AndroidX 我收到以下错误 android view InflateException 二进制 XML 文件行 2 二进制 XM
  • python bokeh,如何制作相关图?

    如何在 Bokeh 中制作相关热图 import pandas as pd import bokeh charts df pd util testing makeTimeDataFrame 1000 c df corr p bokeh ch
  • 使用服务帐号访问 Google Reseller API

    我们在使用服务帐户访问经销商 API 时遇到问题 带有客户端密钥的示例运行良好 但我们需要将其部署在 k8s Kubernetes Engine 中 而不需要定期刷新 oauth 会话 尤其是执行一次 因为在 Docker 容器中有点困难
  • 数据不会导入到 PGAdmin

    找不到 C Program Files PostgreSQL 13 pgAdmin 4 runtime psql exe 文件 请更正首选项对话框中的二进制路径 这是我尝试将数据导入 pg admin 时得到的响应 我之前导入过数据 但没有
  • 将 LIKE 运算符与 DETERMINISTIC 函数结合使用时的 Oracle 执行计划

    现在 当我使用 Oracle 执行计划时 我遇到了一件非常棘手的事情 DETERMINISTIC右侧的功能LIKE操作员 这是我的情况 情况 我认为执行这样的查询 简化的 是明智的 SELECT FROM customers cust JO
  • 在客户端-服务器设置中两个 ESP8266 之间的通信速度更快

    我正在尝试在两个 ESP8266 12 E 模块之间进行通信 一个设置为接入点模式 另一个设置为站 我的目的是在两者之间建立沟通 如何才能使数据传输更快 这就是所谓的TCP IP连接吗 接入点的代码 include
  • PHP JSON 字符串格式错误

    我有一个清理用户输入的功能 干净的输入返回后 会经过 json decode var true 目前 我收到格式错误的字符串错误 不过 如果我打印出来并用它进行测试http jsonlint com 它过去了 我开始意识到 清理过程之后的字
  • python matplotlib 将图形保存为数据文件

    我想创建一个 python 脚本 沿水平轴放大和缩小 matplotlib 图形 我的图是一组水平条形图 我还想让它能够采用任何通用的 matplotlib 图形 我不想只加载图像并放大该图像 我想沿水平轴放大图表 我知道该怎么做 有什么方
  • 如何在 Angular 2 中动态添加和删除表单字段

    我试图在用户单击添加按钮时动态添加输入字段 并且对于每个表单字段必须有一个删除按钮 当用户单击必须删除表单字段时 我需要使用 Angular 2 来实现此目的 如下所示我是 Angular 2 的新手 请帮助我完成它 我尝试过的 我创建了一