Angular 找不到具有未指定名称属性的控件
Angular Cannot find control with unspecified name attribute
我知道这个问题每年都会出现多次,但我听不懂 运行。
我需要根据数组给定的元素动态创建 formArray。尝试了多次,我坚持尝试使用介质:https://medium.com/aubergine-solutions/add-push-and-remove-form-fields-dynamically-to-formarray-with-reactive-forms-in-angular-acf61b4a2afe
我的html:
<mat-accordion class="example-headers-align">
<form [formGroup]="formGroup">
<mat-expansion-panel [expanded]="step === item.step" (opened)="setStep(item.step)" hideToggle
*ngFor="let item of csvColumns; let i = index" formArrayName="selectionArray">
<mat-expansion-panel-header>
<mat-panel-title>
{{item.title}}
</mat-panel-title>
<mat-panel-description>
{{i}} {{item.description}}
</mat-panel-description>
<fa-icon [icon]="['fas', 'list-ul']" size="lg" style="color: grey"></fa-icon>
</mat-expansion-panel-header>
<mat-form-field>
<mat-label>{{'CSV.DBATTR' | translate}}</mat-label>
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto"
[formControl]="selectionArray[i]">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option>{{'CSV.NONE' | translate}}</mat-option>
<mat-optgroup *ngFor="let group of filteredOptions | async" [label]="group.name">
<!-- <fa-icon [icon]="['fas', 'table']" size="lg" class="tree-icons"></fa-icon> -->
<mat-option *ngFor="let children of group.children" [value]="children.name">
<!-- <fa-icon [icon]="['fas', 'tag']" size="md" class="tree-icons"></fa-icon> -->
{{children.name}}
</mat-option>
</mat-optgroup>
</mat-autocomplete>
</mat-form-field>
<mat-action-row>
<button *ngIf="item.step !== 0" mat-button color="warn"
(click)="prevStep()">{{'CSV.PREV' | translate}}</button>
<button *ngIf="item.step < csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.NEXT' | translate}}</button>
<button *ngIf="item.step === csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.END' | translate}}</button>
</mat-action-row>
</mat-expansion-panel>
</form>
</mat-accordion>
解释该代码:*ngFor="let item of csvColumns; let i = index"
它动态创建与我的数组包含的项目一样多的项目。例如。那里的 5 个元素创建了 5 个扩展面板。我需要能够访问用户为此选择下拉列表中的每个元素选择的值。所以我的想法是在为每个面板制作扩展面板的步骤中创建 formControls。
这就是我想使用 formArray 的原因。如果您认为这是一个糟糕的尝试,请告诉我一个更好的尝试。
我的学生:
export class CSVMappingComponent implements OnInit {
@Input() headerColumns: Array<string>;
csvColumns: Array<ExtensionPanelModel>;
filteredOptions: Observable<DatabaseGroup[]>;
databaseGroups: DatabaseGroup[];
formGroup: FormGroup;
constructor(private builder: FormBuilder) {
this.formGroup = this.builder.group({
selectionArray: this.builder.array([])
});
}
// i don't need this but i'm trying everything
createBox(): FormGroup {
return this.builder.group({
name: ''
});
}
get selectionArray() {
return this.formGroup.get('selectionArray') as FormArray;
}
addItems() {
this.csvColumns = [];
for (var i = 0; i < this.headerColumns.length; i++) {
let _step = i.toString();
this.csvColumns.push({ title: this.translateService.instant('CSV.COLUMN') + ": " + this.headerColumns[i], description: this.translateService.instant('CSV.DESCRIPTION'), step: i });
this.selectionArray.push(this.createBox());
// here I really don't know what to do bc I don't need any validator just access the value
// this.selectionArray.push(this.builder.control(false));
}
}
这个 filteredOptions 自动完成功能是以前只有一个 formControl 的东西,但当然不能用。
当我使用 formControlName="{{selectionArray[i]}}
时,错误是 ERROR Error: Cannot find control with unspecified name attribute
或类似 ERROR Error: Cannot find control with path: 'selectionArray -> '
一张截图让你知道它的外观或最终应该是什么样子:
您不能像 selectionArray[i] 一样访问 formarray 控件,试试
<div *ngFor="let control of selectionArray.controls; let i = index">
...
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto" formControlName="{{i}}">
...
</div>
两个让你们知道哪些更改有效:
<mat-accordion class="example-headers-align">
<form [formGroup]="formGroup">
<div formArrayName="selectionArray">
<mat-expansion-panel [expanded]="step === item.step" (opened)="setStep(item.step)" hideToggle
*ngFor="let item of csvColumns; let control of selectionArray.controls; let i = index">
<mat-expansion-panel-header>
<mat-panel-title>
{{item.title}}
</mat-panel-title>
<mat-panel-description>
{{i}} {{item.description}}
</mat-panel-description>
<fa-icon [icon]="['fas', 'list-ul']" size="lg" style="color: grey"></fa-icon>
</mat-expansion-panel-header>
<mat-form-field>
<mat-label>{{'CSV.DBATTR' | translate}}</mat-label>
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto"
formControlName="{{i}}">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option [value]="null">{{'CSV.NONE' | translate}}</mat-option>
<mat-optgroup *ngFor="let group of filteredOptions[i] | async" [label]="group.name">
<fa-icon [icon]="['fas', 'table']" size="lg" class="tree-icons"></fa-icon>
<mat-option *ngFor="let children of group.children"
[value]="[group.name] + ' | ' + [children.name]">
<fa-icon [icon]="['fas', 'tag']" size="md" class="tree-icons"></fa-icon>
{{children.name}}
</mat-option>
</mat-optgroup>
</mat-autocomplete>
</mat-form-field>
<mat-action-row>
<button *ngIf="item.step !== 0" mat-button color="warn"
(click)="prevStep()">{{'CSV.PREV' | translate}}</button>
<button *ngIf="item.step < csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.NEXT' | translate}}</button>
<button *ngIf="item.step === csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.END' | translate}}</button>
</mat-action-row>
</mat-expansion-panel>
</div>
</form>
</mat-accordion>
我知道这个问题每年都会出现多次,但我听不懂 运行。 我需要根据数组给定的元素动态创建 formArray。尝试了多次,我坚持尝试使用介质:https://medium.com/aubergine-solutions/add-push-and-remove-form-fields-dynamically-to-formarray-with-reactive-forms-in-angular-acf61b4a2afe
我的html:
<mat-accordion class="example-headers-align">
<form [formGroup]="formGroup">
<mat-expansion-panel [expanded]="step === item.step" (opened)="setStep(item.step)" hideToggle
*ngFor="let item of csvColumns; let i = index" formArrayName="selectionArray">
<mat-expansion-panel-header>
<mat-panel-title>
{{item.title}}
</mat-panel-title>
<mat-panel-description>
{{i}} {{item.description}}
</mat-panel-description>
<fa-icon [icon]="['fas', 'list-ul']" size="lg" style="color: grey"></fa-icon>
</mat-expansion-panel-header>
<mat-form-field>
<mat-label>{{'CSV.DBATTR' | translate}}</mat-label>
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto"
[formControl]="selectionArray[i]">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option>{{'CSV.NONE' | translate}}</mat-option>
<mat-optgroup *ngFor="let group of filteredOptions | async" [label]="group.name">
<!-- <fa-icon [icon]="['fas', 'table']" size="lg" class="tree-icons"></fa-icon> -->
<mat-option *ngFor="let children of group.children" [value]="children.name">
<!-- <fa-icon [icon]="['fas', 'tag']" size="md" class="tree-icons"></fa-icon> -->
{{children.name}}
</mat-option>
</mat-optgroup>
</mat-autocomplete>
</mat-form-field>
<mat-action-row>
<button *ngIf="item.step !== 0" mat-button color="warn"
(click)="prevStep()">{{'CSV.PREV' | translate}}</button>
<button *ngIf="item.step < csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.NEXT' | translate}}</button>
<button *ngIf="item.step === csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.END' | translate}}</button>
</mat-action-row>
</mat-expansion-panel>
</form>
</mat-accordion>
解释该代码:*ngFor="let item of csvColumns; let i = index"
它动态创建与我的数组包含的项目一样多的项目。例如。那里的 5 个元素创建了 5 个扩展面板。我需要能够访问用户为此选择下拉列表中的每个元素选择的值。所以我的想法是在为每个面板制作扩展面板的步骤中创建 formControls。
这就是我想使用 formArray 的原因。如果您认为这是一个糟糕的尝试,请告诉我一个更好的尝试。
我的学生:
export class CSVMappingComponent implements OnInit {
@Input() headerColumns: Array<string>;
csvColumns: Array<ExtensionPanelModel>;
filteredOptions: Observable<DatabaseGroup[]>;
databaseGroups: DatabaseGroup[];
formGroup: FormGroup;
constructor(private builder: FormBuilder) {
this.formGroup = this.builder.group({
selectionArray: this.builder.array([])
});
}
// i don't need this but i'm trying everything
createBox(): FormGroup {
return this.builder.group({
name: ''
});
}
get selectionArray() {
return this.formGroup.get('selectionArray') as FormArray;
}
addItems() {
this.csvColumns = [];
for (var i = 0; i < this.headerColumns.length; i++) {
let _step = i.toString();
this.csvColumns.push({ title: this.translateService.instant('CSV.COLUMN') + ": " + this.headerColumns[i], description: this.translateService.instant('CSV.DESCRIPTION'), step: i });
this.selectionArray.push(this.createBox());
// here I really don't know what to do bc I don't need any validator just access the value
// this.selectionArray.push(this.builder.control(false));
}
}
这个 filteredOptions 自动完成功能是以前只有一个 formControl 的东西,但当然不能用。
当我使用 formControlName="{{selectionArray[i]}}
ERROR Error: Cannot find control with unspecified name attribute
或类似 ERROR Error: Cannot find control with path: 'selectionArray -> '
一张截图让你知道它的外观或最终应该是什么样子:
您不能像 selectionArray[i] 一样访问 formarray 控件,试试
<div *ngFor="let control of selectionArray.controls; let i = index">
...
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto" formControlName="{{i}}">
...
</div>
两个让你们知道哪些更改有效:
<mat-accordion class="example-headers-align">
<form [formGroup]="formGroup">
<div formArrayName="selectionArray">
<mat-expansion-panel [expanded]="step === item.step" (opened)="setStep(item.step)" hideToggle
*ngFor="let item of csvColumns; let control of selectionArray.controls; let i = index">
<mat-expansion-panel-header>
<mat-panel-title>
{{item.title}}
</mat-panel-title>
<mat-panel-description>
{{i}} {{item.description}}
</mat-panel-description>
<fa-icon [icon]="['fas', 'list-ul']" size="lg" style="color: grey"></fa-icon>
</mat-expansion-panel-header>
<mat-form-field>
<mat-label>{{'CSV.DBATTR' | translate}}</mat-label>
<input matInput placeholder="{{'CSV.CHOOSE' | translate}}" [matAutocomplete]="auto"
formControlName="{{i}}">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option [value]="null">{{'CSV.NONE' | translate}}</mat-option>
<mat-optgroup *ngFor="let group of filteredOptions[i] | async" [label]="group.name">
<fa-icon [icon]="['fas', 'table']" size="lg" class="tree-icons"></fa-icon>
<mat-option *ngFor="let children of group.children"
[value]="[group.name] + ' | ' + [children.name]">
<fa-icon [icon]="['fas', 'tag']" size="md" class="tree-icons"></fa-icon>
{{children.name}}
</mat-option>
</mat-optgroup>
</mat-autocomplete>
</mat-form-field>
<mat-action-row>
<button *ngIf="item.step !== 0" mat-button color="warn"
(click)="prevStep()">{{'CSV.PREV' | translate}}</button>
<button *ngIf="item.step < csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.NEXT' | translate}}</button>
<button *ngIf="item.step === csvColumns.length-1" mat-button color="primary"
(click)="nextStep()">{{'CSV.END' | translate}}</button>
</mat-action-row>
</mat-expansion-panel>
</div>
</form>
</mat-accordion>