如何动态添加 FormArray 项并正确绑定控件和模型?



我有一个日历,它本质上代表了一个巨大的形式。目前没有太多可看的,但现在它得到了一个dates列表,我从中开始构建一个表单:

this.dates.forEach(d => {
group[d] = this._formBuilder.group({
offers: this._formBuilder.array([])
});
});

所以,我真正想要的是:从日期到项目列表的地图

{
'2018-01-01': [{id: 1}, {id: 2}],
'2018-01-02': [{id: 5}, {id: 9}]
}

但是,按照本教程,我目前似乎最终会得到类似的东西:

{
'2018-01-01': {offers: [{id: 1}, {id: 2}]},
'2018-01-02': {offers: [{id: 5}, {id: 9}]}
}

这对我来说已经足够好了 - 我只是想让它工作。

我正在父组件中传递offers表单组:

<form [formGroup]="form" *ngIf="form != null">  
<div fxLayout="row" >  
<app-calendar-day *ngFor="let date of dates$ | async" 
[formGroup]="form.get(date)">
</app-calendar-day>  
</div>  
</form>

到目前为止,这是有效的。

我的问题始于我想向FormArray添加优惠/项目的最后一步。

<div [formGroup]="formGroup">
<mat-card *ngFor="let offer of formGroup.get('offers').controls; let idx = index" style="margin: 4px; padding: 10px;">
<app-offer-item [formGroupName]="idx">
</app-offer-item>
</mat-card>
</div>

日历允许添加项目/优惠,我希望formGroup.get('offers')(FormArray)动态构建s.t。我可以在一天结束时发布整个内容。

但是,我不知道如何正确绑定报价/项目。

app-offer-item基于AbstractControlComponent构建,可提供ControlValueAccessorValidator接口以及一些默认实现。OfferItemComponent又名app-offer-item的代码如下。由于它封装了一个对象,我很确定这个元素应该代表一个FormGroup但我无法像看起来那样正确地将这些部分连接在一起。

上面的代码给了我

错误

错误: 找不到具有未指定名称属性的控件

这似乎发生在我向FormArray添加项目/优惠之后:

onAddOffer(offer) {
const formArray = <FormArray> this.formGroup.get('offers');
formArray.push(this._formBuilder.group(offer));
// ..
}

我希望OfferItemComponent中的writeValue()以某种方式被称为,但我想这不是它的工作原理。

我想我在这里有两个选择:

  1. 毕竟想办法让这项工作
  2. 额外的FormGroup传递给OfferItemComponent并尝试使其像那样工作

任何帮助都非常感谢!


报价项组件

@Component({
selector: 'app-offer-item',
styles: [`
`],
template: `
<div>      
<div [innerHTML]="getItemHtml()"></div>
<div>
<span style="padding-right: 4px;">€</span>
<mat-form-field style="text-align: right; width: 55px; margin-bottom: -1.25em;">
<input matInput autocomplete="off" (focusout)="formatPrice($event.target)"/>
</mat-form-field>        
</div>
</div>
`,
providers: [
DecimalPipe,
ValueAccessorProvider(OfferItemComponent),
ValidatorsProvider(OfferItemComponent)
]
})
export class OfferItemComponent extends AbstractControlComponent {
@Input()
items;
offer: OfferModel;
constructor(
@Inject(LOCALE_ID) public locale: string,
private _decimalPipe: DecimalPipe
) {
super();
}
writeValue(offer: OfferModel): void {
this.offer = offer;
this._onChangeCallback(this.offer);
}
validate(c: AbstractControl): ValidationErrors | any {
// ..
}
getItemHtml() {
// ..
}
formatPrice(element) {
// ..
}
}

我相信[formGroup]中的所有表单控件元素也需要设置"name"和"formControlName"属性。

[attr.data-name]="name_of_field" [formControlName]="name_of_field"

代码中缺少的元素是formArrayName

<div formArrayName="offers">
<mat-card *ngFor="let offer of formGroup.get('offers').controls; let idx = index" style="margin: 4px; padding: 10px;">
<app-offer-item [formGroupName]="idx">
</app-offer-item>
</mat-card>
</div>

最新更新