[英]Angular 14: deleting items from FormArray clears the values of remaining items
I created a form using custom inputs and ControlValueAccessor
which you can see here .我使用自定义输入和
ControlValueAccessor
创建了一个表单,您可以在此处看到。 After finally getting it to work I noticed whenever I delete an item from a FormArray
it clears the values of the other FormGroups
still present in the array.在终于让它工作之后,我注意到每当我从
FormArray
中删除一个项目时,它都会清除数组中仍然存在的其他FormGroups
的值。 If you run the demo and click on the add-media-query
button a couple times and fill one out then delete one of the others you'll see what I mean.如果您运行演示并单击
add-media-query
按钮几次并填写一个然后删除其他一个,您会明白我的意思。 The code bellow is an example of how I have everything set up.下面的代码是我如何设置所有内容的示例。
The form表格
SvgForm : FormGroup<SvgForm> = new FormGroup<SvgForm>({
title: new FormControl<string>(''),
graphicId: new FormControl<string>(''),
svgInput : new FormControl<string>(''),
viewBox : new FormGroup<ViewBoxParams>({
x: new FormControl<string>(''),
y: new FormControl<string>(''),
width: new FormControl<string>(''),
height: new FormControl<string>('')
}),
styling: new FormGroup<StylingParams>({
globalStyles: new FormControl<string>(''),
mediaQueries: new FormArray<FormGroup<MediaQueryParams>>([])
})
});
Inside the template I pass the styling
FormGroup into a custom component called styling-input
through an @Input()
like so在模板中,我通过
@Input()
将styling
FormGroup 传递给一个名为styling-input
输入的自定义组件,如下所示
<styling-input [StylingForm]="SvgForm.controls.styling"></styling-input>
This is how the styling-input
is set up.这就是
styling-input
的设置方式。
styling-input.component.ts样式输入.component.ts
@Component({
selector: 'styling-input',
templateUrl: './styling-input.component.html',
styleUrls: ['./styling-input.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: StylingInputComponent,
multi: true
}
]
})
export class StylingInputComponent implements ControlValueAccessor{
@Input() StylingForm!: FormGroup<StylingParams>;
get MediaQueryList() {
return this.StylingForm.get('mediaQueries') as FormArray<FormGroup<MediaQueryParams>>;
}
writeValue(value: any){ if(value){ this.StylingForm.setValue(value); } }
registerOnChange(fn: any){ this.StylingForm.valueChanges.subscribe(fn); }
registerOnTouched(onTouched: Function){}
private createMediaQueryGroup(): FormGroup<MediaQueryParams> {
return new FormGroup<MediaQueryParams>({
selectorParams: new FormGroup<MediaSelectorParams>({
mediaType: new FormControl<MediaTypeParams>('all'),
expressions: new FormArray<FormGroup<MediaExpressionGroupParams>>([]),
}),
rules: new FormControl<string>('')
});
}
public addMediaQuery():void{
this.MediaQueryList.push(this.createMediaQueryGroup());
}
public removeMediaQuery(item: number): void{
this.MediaQueryList.removeAt(item);
}
}
Then inside the template I iterate over the MediaQueryList
getter like this然后在模板中我像这样遍历
MediaQueryList
getter
<article formArrayName="mediaQueries">
<media-query-input *ngFor="let a of MediaQueryList.controls; let i = index"
[MediaQueryForm]="a"
[attr.GroupId]="i"
(RemoveGroup)="removeMediaQuery($any($event))"
></media-query-input>
</article>
The property MediaQueryForm
is an @Input()
that I pass the FormGroup
into and the i
variable is passed back up through the RemoveGroup
Output once a delete
button is pushed and you can see in the code above the removeMediaQuery()
function uses removeAt()
on the MediaQueryList
.属性
MediaQueryForm
是一个@Input()
,我将FormGroup
传递到其中,一旦按下delete
按钮, i
变量就会通过RemoveGroup
Output 向上传递,您可以在上面的代码中看到removeMediaQuery()
function 使用removeAt()
在MediaQueryList
上。
I haven't really tried anything different as this is the suggested way to remove an element from a FormArray
, however due to me using ControlValueAccessor
I'm guessing there may be some other things going on under the hood that I'm not aware of.我没有真正尝试过任何不同的事情,因为这是从
FormArray
中删除元素的建议方法,但是由于我使用ControlValueAccessor
我猜可能还有其他一些我不知道的事情发生在幕后. Does anybody know why this happens and how to fix it?有谁知道为什么会发生这种情况以及如何解决它?
You are not passing GroupId
input value to the media-query-input component.您没有将
GroupId
输入值传递给 media-query-input 组件。
Instead of setting attribute value pass input using without attr prefix.而不是使用不带 attr 前缀的方式设置属性值传递输入。
[attr.GroupId]="i" ===> [GroupId]="i"
styling.input.component样式.输入.组件
<media-query-input *ngFor="let a of MediaQueryList.controls; let i = index"
[MediaQueryForm]="a"
[GroupId]="i"
(RemoveGroup)="removeMediaQuery($any($event))" >
</media-query-input>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.