Angular2 - 带有数据数组的反应形式
Angular2 - Reactive Forms w/ Arrays of Data
我的组件中有一个表单设置,用户可以在其中修改最多三个班次容器,其中包括开始时间、结束时间和星期几。
无需将一堆代码重复三次,我正在尝试找出最动态的方法来解决这个问题。
这是我目前的 HTML 一个班次:
<span formGroupName="slice" *ngFor="let slice of [1,2,3]">
<table class="table table-condensed">
<thead>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th style="text-align:center;">Enable</th>
</thead>
<tbody>
<tr>
<td class="col-md-2" style="text-align:center; vertical-align:middle">
Time Slice {{ slice }}
</td>
<td>
<select name="hour_start" class="form-control input-sm" formControlName="hour_start">
<option value="{{ h }}" *ngFor="let h of hours">{{ h }}</option>
</select>
</td>
<td>
<select name="minute_start" class="form-control input-sm" formControlName="minute_start">
<option value="{{ m }}" *ngFor="let m of minutes">{{ m }}</option>
</select>
</td>
<td>
<select name="period_start" class="form-control input-sm" formControlName="period_start">
<option value="{{ p }}" *ngFor="let p of period">{{ p }}</option>
</select>
</td>
<td style="text-align:center; vertical-align:middle;">-</td>
<td>
<select name="hour_end" class="form-control input-sm" formControlName="hour_end">
<option value="{{ h }}" *ngFor="let h of hours">{{ h }}</option>
</select>
</td>
<td>
<select name="minute_end" class="form-control input-sm" formControlName="minute_end">
<option value="{{ m }}" *ngFor="let m of minutes">{{ m }}</option>
</select>
</td>
<td>
<select name="period_end" class="form-control input-sm" formControlName="period_end">
<option value="{{ p }}" *ngFor="let p of period">{{ p }}</option>
</select>
</td>
<td style="vertical-align:middle; text-align:center;"><input type="checkbox" (change)="toggleSlice(slice, true)"></td>
</tr>
<tr>
<td class="col-md-2"></td>
<td colspan="7">
<table class="table table-condensed" formGroupName="days">
<tbody>
<tr>
<td *ngFor="let d of days">
<div class="checkbox">
<label>
<input type="checkbox" formControlName="day_{{ d }}"> {{ d }}
</label>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</span>
<!-- Time Slice -->
</span>
这是我的组件:
this.transitionForm = this.fb.group({
shift: this.fb.group({
slice: this.fb.group({
hour_start: { value: '1', disabled: true },
minute_start: { value: '00', disabled: true },
period_start: { value: 'AM', disabled: true },
hour_end: { value: '1', disabled: true },
minute_end: { value: '00', disabled: true },
period_end: { value: 'AM', disabled: true },
days: this.fb.group({
day_Su: { value: '', disabled: true },
day_M: { value: '', disabled: true },
day_Tu: { value: '', disabled: true },
day_W: { value: '', disabled: true },
day_Th: { value: '', disabled: true },
day_F: { value: '', disabled: true },
day_Sa: { value: '', disabled: true }
})
})
})
});
关于其他小细节,每个班次行都包含一个 enable/disable 复选框,因此我可以根据需要选择使用其他两个班次容器,否则它们将被禁用。
现在使用 jQuery 之类的东西,我可以通过获取此复选框的父元素并以这种方式处理每组数据(移位)来完成此操作。不过,我的目标是不需要使用 jQuery 并找出可以针对这种情况提供哪些反应形式。
问题:
我怎样才能使用反应形式将这三个时间片(转变)形成一个更动态的设置,而不是为每个时间片硬编码。响应式表单可以处理这个问题吗?
是的,您可以使用 Form Arrays 动态添加和删除响应式表单的部分。
有一个很好的博客 post 涵盖了这个 here,我在下面包含了一些相关的文章
组件
ngOnInit() {
// we will initialize our form here
this.myForm = this._fb.group({
name: ['', [Validators.required, Validators.minLength(5)]],
addresses: this._fb.array([
this.initAddress(),
])
});
}
initAddress() {
// initialize our address
return this._fb.group({
street: ['', Validators.required],
postcode: ['']
});
}
addAddress() {
// add address to the list
const control = <FormArray>this.myForm.controls['addresses'];
control.push(this.initAddress());
}
removeAddress(i: number) {
// remove address from the list
const control = <FormArray>this.myForm.controls['addresses'];
control.removeAt(i);
}
HTML
<!-- list of addresses -->
<div formArrayName="addresses">
<div *ngFor="let address of myForm.controls.addresses.controls; let i=index">
<!-- address header, show remove button when more than one address available -->
<div>
<span>Address {{i + 1}}</span>
<span *ngIf="myForm.controls.addresses.controls.length > 1" (click)="removeAddress(i)">
</span>
</div>
<!-- Angular assigns array index as group name by default 0, 1, 2, ... -->
<div [formGroupName]="i">
<!--street-->
<div>
<label>street</label>
<input type="text" formControlName="street">
<!--display error message if street is not valid-->
<small [hidden]="myForm.controls.addresses.controls[i].controls.street.valid">
Street is required
</small>
</div>
<!--postcode-->
<div>
<label>postcode</label>
<input type="text" formControlName="postcode">
</div>
<div>
</div>
</div>
我的组件中有一个表单设置,用户可以在其中修改最多三个班次容器,其中包括开始时间、结束时间和星期几。
无需将一堆代码重复三次,我正在尝试找出最动态的方法来解决这个问题。
这是我目前的 HTML 一个班次:
<span formGroupName="slice" *ngFor="let slice of [1,2,3]">
<table class="table table-condensed">
<thead>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th style="text-align:center;">Enable</th>
</thead>
<tbody>
<tr>
<td class="col-md-2" style="text-align:center; vertical-align:middle">
Time Slice {{ slice }}
</td>
<td>
<select name="hour_start" class="form-control input-sm" formControlName="hour_start">
<option value="{{ h }}" *ngFor="let h of hours">{{ h }}</option>
</select>
</td>
<td>
<select name="minute_start" class="form-control input-sm" formControlName="minute_start">
<option value="{{ m }}" *ngFor="let m of minutes">{{ m }}</option>
</select>
</td>
<td>
<select name="period_start" class="form-control input-sm" formControlName="period_start">
<option value="{{ p }}" *ngFor="let p of period">{{ p }}</option>
</select>
</td>
<td style="text-align:center; vertical-align:middle;">-</td>
<td>
<select name="hour_end" class="form-control input-sm" formControlName="hour_end">
<option value="{{ h }}" *ngFor="let h of hours">{{ h }}</option>
</select>
</td>
<td>
<select name="minute_end" class="form-control input-sm" formControlName="minute_end">
<option value="{{ m }}" *ngFor="let m of minutes">{{ m }}</option>
</select>
</td>
<td>
<select name="period_end" class="form-control input-sm" formControlName="period_end">
<option value="{{ p }}" *ngFor="let p of period">{{ p }}</option>
</select>
</td>
<td style="vertical-align:middle; text-align:center;"><input type="checkbox" (change)="toggleSlice(slice, true)"></td>
</tr>
<tr>
<td class="col-md-2"></td>
<td colspan="7">
<table class="table table-condensed" formGroupName="days">
<tbody>
<tr>
<td *ngFor="let d of days">
<div class="checkbox">
<label>
<input type="checkbox" formControlName="day_{{ d }}"> {{ d }}
</label>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</span>
<!-- Time Slice -->
</span>
这是我的组件:
this.transitionForm = this.fb.group({
shift: this.fb.group({
slice: this.fb.group({
hour_start: { value: '1', disabled: true },
minute_start: { value: '00', disabled: true },
period_start: { value: 'AM', disabled: true },
hour_end: { value: '1', disabled: true },
minute_end: { value: '00', disabled: true },
period_end: { value: 'AM', disabled: true },
days: this.fb.group({
day_Su: { value: '', disabled: true },
day_M: { value: '', disabled: true },
day_Tu: { value: '', disabled: true },
day_W: { value: '', disabled: true },
day_Th: { value: '', disabled: true },
day_F: { value: '', disabled: true },
day_Sa: { value: '', disabled: true }
})
})
})
});
关于其他小细节,每个班次行都包含一个 enable/disable 复选框,因此我可以根据需要选择使用其他两个班次容器,否则它们将被禁用。
现在使用 jQuery 之类的东西,我可以通过获取此复选框的父元素并以这种方式处理每组数据(移位)来完成此操作。不过,我的目标是不需要使用 jQuery 并找出可以针对这种情况提供哪些反应形式。
问题:
我怎样才能使用反应形式将这三个时间片(转变)形成一个更动态的设置,而不是为每个时间片硬编码。响应式表单可以处理这个问题吗?
是的,您可以使用 Form Arrays 动态添加和删除响应式表单的部分。
有一个很好的博客 post 涵盖了这个 here,我在下面包含了一些相关的文章
组件
ngOnInit() {
// we will initialize our form here
this.myForm = this._fb.group({
name: ['', [Validators.required, Validators.minLength(5)]],
addresses: this._fb.array([
this.initAddress(),
])
});
}
initAddress() {
// initialize our address
return this._fb.group({
street: ['', Validators.required],
postcode: ['']
});
}
addAddress() {
// add address to the list
const control = <FormArray>this.myForm.controls['addresses'];
control.push(this.initAddress());
}
removeAddress(i: number) {
// remove address from the list
const control = <FormArray>this.myForm.controls['addresses'];
control.removeAt(i);
}
HTML
<!-- list of addresses -->
<div formArrayName="addresses">
<div *ngFor="let address of myForm.controls.addresses.controls; let i=index">
<!-- address header, show remove button when more than one address available -->
<div>
<span>Address {{i + 1}}</span>
<span *ngIf="myForm.controls.addresses.controls.length > 1" (click)="removeAddress(i)">
</span>
</div>
<!-- Angular assigns array index as group name by default 0, 1, 2, ... -->
<div [formGroupName]="i">
<!--street-->
<div>
<label>street</label>
<input type="text" formControlName="street">
<!--display error message if street is not valid-->
<small [hidden]="myForm.controls.addresses.controls[i].controls.street.valid">
Street is required
</small>
</div>
<!--postcode-->
<div>
<label>postcode</label>
<input type="text" formControlName="postcode">
</div>
<div>
</div>
</div>