Angular 2动态嵌套表单 [英] Angular 2 Dynamic Nested Form
问题描述
基本上,我想创建一个带有嵌套对象的动态表单,如下图所示:
Basically I want to create a dynamic form with nested objects like the picture below:
- 还清货款在模型上的数组中
- 我们应该能够根据需要添加/删除收益.
- 表单应同步基础表单控件和模型
- 收益的数量是任意的,应该从模型中加载到表格中
虽然在Angular 1中确实很容易做到,但我在Angular 2中没有找到如何工作的示例.
There are no working examples that I could find as how to do this in Angular 2, although this was really easy to do in Angular 1.
以下是我的原始问题,此后我进行了更新以进行澄清(请参见上文):
Below is my original question, I've since updated it for clarification (see above):
首先,我想指出的是,我知道几天前刚刚发布了新版本的Angular 2 rc.2.因此,用于创建动态嵌套表单的代码可能已经进行了一些更改,但是没有足够的文档来解决这个问题.
First I just wanted to point out that I'm aware that a new version of Angular 2 rc.2 has just been released a few days ago. So the code for creating a dynamic, nested form may have changed some but there's not enough documentation to figure this out.
在Angular 2的最新版本中(我目前正在使用rc.1,但计划更新到rc.2),我需要创建一个这样的表单(视图的伪代码):
In the latest version(s) of Angular 2 (I'm currently using rc.1 but planning to update to rc.2) I need to create a form like this (pseudo-code of view):
<form [ngFormModel]="form" (ngSubmit)="onSubmit()">
<input type="text" ngControl="name">
<div *ngFor="let expense for expenses; let i = index;" control-group="expenses">
<input type="text" ngControl="expense.amount" [(ngModel)]="myModel.expenses[i].amount">
<input type="checkbox" ngControl="expense.final" [(ngModel)]="myModel.expenses[i].final">
</div>
<a class="button" (click)="addExpenseControl()">Add</a>
<a class="button" (click)="deleteExpenseControl()">Delete</a>
</form>
因此,上面的伪代码将不起作用,但老实说,由于缺乏文档,我无法弄清楚如何进行此类连接.有一些关于嵌套ControlGroup的教程,但是这里不适合这种情况,因为我们需要能够动态地添加和删除控件组,并且还需要能够将它们与模型同步.
So the pseudo-code above won't work but to be honest because of lack of documentation I can't figure out how to wire something like this up. There's a few tutorials about nested ControlGroup but this won't fit the case here since we need to be able to dynamically add and remove control groups, and also I need to be able to sync them with a model.
我发现了这个 plunkr ,这里是Angular小组提供的,它允许将控件添加到表单中-但是不是添加/删除 ControlGroup ,而是使用ControlArray,我不确定这是否适用于此?
I found this plunkr here provided by Angular team which allows adding of Controls to a form--but this is not adding/removing a ControlGroup, rather it's using ControlArray and I'm not sure if that applies here?
我对使用较新的基于模型的Angular 2表单非常熟悉,但是我正在抓紧资源以正确地嵌套它们(动态!),并将嵌套的数据绑定到主表单模型中.我将如何在视图中引用嵌套控件?上面的伪代码是否接近?我会从我的控制器中发布代码,但老实说,当涉及上述嵌套费用(ControlGroup ??)时,我不知道从哪里开始...
I'm very familiar with using the newer model-based Angular 2 forms however I'm grasping for resources in order to properly nest them (dynamically!), and tie this nested data into the main form model. How would I refer to nested controls in the view? Is the pseudo-code above even close? I'd post code from my controller but honestly I wouldn't know where to start when it comes to the nested expenses (ControlGroup ??) above...
推荐答案
我不得不自己弄清楚这个问题,因为在Angular 2中,表单似乎仍在变化,而且我还没有看到其他类似的示例(尽管这似乎是一个非常常见的用例).
I had to figure this out on my own because it seems that forms are still changing in Angular 2 and I've not seen any other examples similar to this (although it seems like a very common use-case).
我正在使用此文档中的更新的Angular 2表单代码.
I am using updated Angular 2 form code from this document.
app.component.ts(包含表单):
import { Component } from '@angular/core';
import {REACTIVE_FORM_DIRECTIVES, FormControl, FormGroup, FormArray} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: 'app/app.html',
directives: [REACTIVE_FORM_DIRECTIVES],
providers: []
})
export class AppComponent {
form: FormGroup;
myModel:any;
constructor() {
// initializing a model for the form to keep in sync with.
// usually you'd grab this from a backend API
this.myModel = {
name: "Joanna Jedrzejczyk",
payOffs: [
{amount: 111.11, date: "Jan 1, 2016", final: false},
{amount: 222.22, date: "Jan 2, 2016", final: true}
]
}
// initialize form with empty FormArray for payOffs
this.form = new FormGroup({
name: new FormControl(''),
payOffs: new FormArray([])
});
// now we manually use the model and push a FormGroup into the form's FormArray for each PayOff
this.myModel.payOffs.forEach(
(po) =>
this.form.controls.payOffs.push(this.createPayOffFormGroup(po))
);
}
createPayOffFormGroup(payOffObj) {
console.log("payOffObj", payOffObj);
return new FormGroup({
amount: new FormControl(payOffObj.amount),
date: new FormControl(payOffObj.date),
final: new FormControl(payOffObj.final)
});
}
addPayOff(event) {
event.preventDefault(); // ensure this button doesn't try to submit the form
var emptyPayOff = {amount: null, date: null, final: false};
// add pay off to both the model and to form controls because I don't think Angular has any way to do this automagically yet
this.myModel.payOffs.push(emptyPayOff);
this.form.controls.payOffs.push(this.createPayOffFormGroup(emptyPayOff));
console.log("Added New Pay Off", this.form.controls.payOffs)
}
deletePayOff(index:number) {
// delete payoff from both the model and the FormArray
this.myModel.payOffs.splice(index, 1);
this.form.controls.payOffs.removeAt(index);
}
}
上面的通知是我将新的FormGroup对象手动推入form.controls.payOffs数组中,它是一个FormArray对象.
Notice above that I manually push new FormGroup objects into the form.controls.payOffs array, which is a FormArray object.
app.html (包含html格式):
app.html (contains form html):
<form (ngSubmit)="onSubmit()" [formGroup]="form">
<label>Name</label>
<input type="text" formControlName="name" [(ngModel)]="myModel.name" placeholder="Name">
<p>Pay Offs</p>
<table class="simple-table">
<tr>
<th>Amount</th>
<th>Date</th>
<th>Final?</th>
<th></th>
</tr>
<tbody>
<tr *ngFor="let po of form.find('payOffs').controls; let i = index">
<td>
<input type="text" size=10 [formControl]="po.controls.amount" [(ngModel)]="myModel.payOffs[i].amount">
</td>
<td>
<input type="text" [formControl]="po.controls.date" [(ngModel)]="myModel.payOffs[i].date">
</td>
<td>
<input type="checkbox" [formControl]="po.controls.final" [(ngModel)]="myModel.payOffs[i].final">
</td>
<td>
<button (click)="deletePayOff(i)" style="color: white; background: rgba(255, 0, 0, .5)">x</button>
</td>
</tr>
</tbody>
<tr>
<td colspan="4" style="text-align: center; padding: .5em;">
<button (click)="addPayOff($event)" style="color: white; background: rgba(0, 150, 0, 1)">Add Pay Off</button>
</td>
</tr>
</table>
</form>
在html表单中,我使用如下语句将表单链接到输入模型:
In the html form I link the form to the model on the inputs with statements like so:
... [formControl]="po.controls.amount" [(ngModel)]="myModel.payOffs[i].amount" ...
这篇关于Angular 2动态嵌套表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!