Как мы обрабатываем FormArrays и FormGroups с помощью ControlValueAccessor в Angular 14?
Я создаю форму с пользовательскими данными, используяControlValueAccessor
который можно посмотреть здесь , на stackblitz, и кажется, что всякий раз, когда он входит в уравнение, все выходит из-под контроля. Я также заметил, что мне нужно использоватьFormControlName
on s, чтобы изменения были обновлены в родительской форме.
Моя общая форма выглядит так
export class SvgParserComponent implements OnInit{
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>>([])
})
});
//other code
}
Шаблон для этого уровня формы выглядит так
<form class="mainGrid" [formGroup]="SvgForm" (ngSubmit)="submitForm()">
<p>svg parser</p>
<code-input formControlName="svgInput"></code-input>
<text-input formControlName="title" [label]="'title'"></text-input>
<text-input formControlName="graphicId" [label]="'graphic id'"></text-input>
<viewbox-input formControlName="viewBox"></viewbox-input>
<styling-input formGroupName="styling"></styling-input>
<button type="submit">submit</button>
</form>
Если вы посмотрите наviewbox-input
вы увидите, что у меня есть этот набор с, а не потому, что введенные значения не будут обновляться в родительском компоненте в противном случае. Однако это создает проблемы, если я устанавливаю его, поэтому я просто оставил его как .
Внутри есть a, который повторяет a, в котором есть FormsGroups и FormArrays. У меня настроено так.
@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{
StylingForm: FormGroup<StylingParams> = new FormGroup<StylingParams>({
globalStyles: new FormControl<string>(''),
mediaQueries: new FormArray<FormGroup<MediaQueryParams>>([])
});
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);
}
}
и шаблон для этого компонента выглядит так
<article [formGroup]="StylingForm">
<p>Styles</p>
<code-input formControlName="globalStyles"></code-input>
<section>
<article formArrayName="MediaQueryList">
<media-query-input *ngFor="let a of MediaQueryList.controls; let i = index"
[formGroupName]="i"
[attr.GroupId]="i"
(RemoveGroup)="removeMediaQuery($any($event))"
></media-query-input>
</article>
<article>
<button type="button" (click)="addMediaQuery()">add media query</button>
</article>
</section>
</article>
Итак, внутри этого шаблона у меня естьcode-input
что такое и что такоеFormGroup
который повторяется из . На данный момент я получаю следующие ошибки
control.registerOnChange не является функцией
Не удается найти элемент управления с именем: «MediaQueryList»
затем, когда я нажимаюadd media query
кнопка отображает другой компонент, и появляется эта ошибка
Не удается найти элемент управления с путем: «MediaQueryList -> 0»
Внутри у меня есть еще одинFormControl
иFormArray
это выглядит странно, показывая, что что-то явно не так, и я предполагаю, что это просто рекурсия той же проблемы, с которой я сталкиваюсь вstyling-input
с правильной итерацией и рендерингомmedia-query-input
.
я пытался переключитьсяformGroupName
дляformControlName
и даже пытался[attr.formControlName]
в некоторых местах я добавилforwardRef(()=> Component)
кuseExisting
собственность в моемproviders
что привело к ошибкам, сообщающим мне, что элементы управления и группы еще не существовали. Как я должен структурировать это, чтобы все работало?