为什么在我的反应形式中的 FormArray 发生变化后,我会收到此错误消息,从 JSON 文件中检索对象?
Why am I obtaining this error message retrieving objects from a JSON file after this FormArray changes in my reactive form?
我正在做一个 Angular 项目,使用反应形式并引入 FormArray(因为我有一个字段被动态创建为多个字段的情况)我是面临以下问题。
基本上是一个定义我的 HTML 代码的表格我有这样的东西:
<div class="col-10">
<ng-container *ngFor="let commessa of commessaList.controls; index as idx">
<div class="row">
<div class="col-sm-8">
<input type="text" [ngClass]="{'error':commessa.invalid && commessa.touched}"
[formControlName]="idx"
class="form-control" id="commessa">
</div>
<div class="col-sm-2">
<button type="button" *ngIf="idx===0" (click)="addCommessaField()" class="btn btn-success"
[ngClass]="'pad'"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
<button (click)="deleteCommessaField(idx)" *ngIf="idx!==0" class="btn btn-danger">
<i class="fa fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</ng-container>
</div>
</div>
此部分用于定义我的表单的突出显示部分(我可以在其中添加多个“Commessa”字段:
然后在我的 TypeScript 代码中定义了 orderForm: FormGroup; 对象,我用它来定义表单字段和相关的验证规则,我将它设置到 ngOnInit() 方法:
ngOnInit() {
this.orderFormValues = new OrderFormValues();
console.log("orderFormValues VALUES: " + this.orderFormValues.statoOrdine);
this.orderForm = this.fb.group({
idOrdine: [null, [Validators.required]],
dataInserimentoOrdine: [new Date(), [Validators.required]],
statoOrdine: [null, [Validators.required, Validators.minLength(5)]],
//commessa: [null, [Validators.required, Validators.minLength(5)]],
commessaList: new FormArray([
new FormControl('', [Validators.required, Validators.minLength(5)])
]),
CIG: [null, [Validators.required, Validators.pattern("^[a-zA-Z0-9]{10}$")]],
dataInizioAttivita: [null, [Validators.required]],
dataFineAttivita: [null, [Validators.required]],
referente: [null, [Validators.required]],
ruoloReferente: [null, [Validators.required]],
tipologiaDiPartecipazione: [null, [Validators.required, Validators.minLength(5)]],
quotaPercentualeDiRTI: [null, [Validators.max(100)]],
cliente: [null, [Validators.required]],
vatCliente: [null, [Validators.required]],
clienteFinale: [null, []],
vatClienteFinale: [null, []],
tipologiaContratto: [null, []],
importoContratto: [null, [Validators.required]],
linkContratto: [null, [Validators.required]],
dataSottoscrizioneContratto: [null, [Validators.required]],
nomeSocieta: [null, [Validators.required]],
vatSocieta: [null, []],
buName: [null, [Validators.required]],
presenzaAQ: [false, [Validators.required]],
linkIdentificativoAQ: [null, []],
accordoQuadro: [null, []],
residuoAccordoQuadro: [null, []],
compagineDiAQ: [null, []]
});
this.ordersService.getAllOrders().then(orders => {
this.orders = orders;
console.log("RETRIEVED ORDERS: ", orders);
this.loading = false;
});
.........................................................................................
.........................................................................................
.........................................................................................
}
正如您在 FormGroup 定义中看到的,与多个“Commessa”字段相关的部分以这种方式定义为 FormArray :
commessaList: new FormArray([
new FormControl('', [Validators.required, Validators.minLength(5)])
]),
为了完整起见,我在我的 TypeScript 代码中添加了这两种方法,用于将用户插入的值插入多个 Commessa 字段中 FormArray 对象:
addCommessaField() {
this.commessaList.push(new FormControl('', [Validators.required, Validators.minLength(5)]));
}
deleteCommessaField(index: number) {
if (this.commessaList.length !== 1) {
this.commessaList.removeAt(index);
}
console.log(this.commessaList.length);
}
正如您在我的 ngOnInit() 方法中的前一个代码片段中所见,我也在执行对 OrderService 对象的调用:
this.ordersService.getAllOrders().then(orders => {
this.orders = orders;
console.log("RETRIEVED ORDERS: ", orders);
this.loading = false;
});
此调用只是检索显示在主页中的订单列表(目前模拟到 JSON 文件中),我在这里遇到一个奇怪的错误。
我的getAllOrders()服务方法的代码就是这个:
getAllOrders() {
return this.http.get<any>('assets/json_mock/ordini.json')
.toPromise()
.then(res => <Order[]>res.data)
.then(data => { return data; });
}
如您所见,它从 ordini.json 文件中检索和 return 订单。
问题是调用 getAllOrders() 服务方法它检索订单列表,但在 Chrome 控制台中我也收到此错误消息:
core.js:6228 ERROR Error: Cannot find control with name: '0'
at _throwError (forms.js:3576)
at setUpControl (forms.js:3398)
at FormGroupDirective.addControl (forms.js:7679)
at FormControlName._setUpControl (forms.js:8451)
at FormControlName.ngOnChanges (forms.js:8368)
at FormControlName.wrapOnChangesHook_inPreviousChangesStorage (core.js:26966)
at callHook (core.js:4730)
at callHooks (core.js:4690)
at executeInitAndCheckHooks (core.js:4630)
at selectIndexInternal (core.js:9748)
奇怪的是,它发生在我使用之前的 FormArray 实现这个多个“Commessa”字段之后(在我只有一个“Commessa”输入字段之前,我没有这个错误)。我怀疑错误可能出在我原来的 JSON 内容中,但我不明白为什么以及如何解决这个问题。
按照我的 ordini.json 文件的内容:
{
"data": [
{
"id": 1,
"referente": {
"name": "Mario",
"surname": "Rossi",
"complete_name": "Mario Rossi",
"role": "Operation Manager",
"avatar": "mario-rossi.jpg"
},
"company": {
"name": "TEST S.p.A.",
"VAT": "IT 03318271214",
"BU": {
"name": "Digital Solution",
"code": "DS"
}
},
"dettaglio_ordine": {
"data_inserimento": "08/08/2020",
"commessa": {
"code": "AAA0001"
},
"identificativo_contratto_hyperlink": "LINK-ID-CONTRATTO-TEST",
"tipologia_contratto": "ORDINE",
"presenza_AQ": true,
"identificativo_AQ_hyperlink": "LINK-AQ-TEST",
"accordo_quadro": 12,
"importo_contratto": 122000,
"residuo_AQ": 20000,
"compagine_di_AQ": "COMPAGINE-DI-AQ-TEST",
"quota_percentuale_di_RTI": 20,
"tipologia_di_partecipazione": "GARA PUBBLICA",
"cig": "CIG-TEST-1",
"cliente": "CLIENTE-TEST-1",
"vat_cliente": "VAT-CLIENTE",
"cliente_finale": "CLIENTE-FINALE-TEST-1",
"vat_cliente_finale": "VAT-CLIENTE-FINALE",
"data_sottoscrizione_contratto": "8/12/2020",
"data_inizio_attivita": "8/28/2020",
"data_fine_attivita": "8/31/2020",
"stato_ordine": "CHIUSO"
}
},
{
"id": 2,
"referente": {
"name": "Mario",
"surname": "Rossi",
"complete_name": "Mario Rossi",
"role": "Operation Manager",
"avatar": "mario-rossi.jpg"
},
"company": {
"name": "Blabla S.p.A.",
"VAT": "IT 03318271214",
"BU": {
"name": "Cyber Security",
"code": "CS"
}
},
"dettaglio_ordine": {
"data_inserimento": "09/08/2020",
"commessa": {
"code": "AAA0002"
},
"identificativo_contratto_hyperlink": "LINK-ID-CONTRATTO-TEST",
"tipologia_contratto": "ORDINE",
"presenza_AQ": false,
"identificativo_AQ_hyperlink": "LINK-AQ-TEST",
"accordo_quadro": 12,
"importo_contratto": 122000,
"residuo_AQ": 20000,
"compagine_di_AQ": "COMPAGINE-DI-AQ-TEST",
"quota_percentuale_di_RTI": 20,
"tipologia_di_partecipazione": "GARA PUBBLICA",
"cig": "CIG-TEST-2",
"cliente": "CLIENTE-TEST-1",
"vat_cliente": "VAT CLIENTE TEST",
"cliente_finale": "CLIENTE-FINALE-TEST-2",
"vat_cliente_finale": "VAT-CLIENTE-FINALE-TEST",
"data_sottoscrizione_contratto": "8/12/2020",
"data_inizio_attivita": "8/28/2020",
"data_fine_attivita": "8/31/2020",
"stato_ordine": "CHIUSO"
}
},
{
"id": 3,
"referente": {
"name": "Francesco Nicola",
"surname": "Romano",
"complete_name": "Francesco Verdi",
"role": "Operation Manager",
"avatar": "francesco-romano.jpg"
},
"company": {
"name": "Blabla S.p.A.",
"VAT": "IT 03318271214",
"BU": {
"name": "Cyber Security",
"code": "CS"
}
},
"dettaglio_ordine": {
"data_inserimento": "10/08/2020",
"commessa": {
"code": "AAA0002"
},
"identificativo_contratto_hyperlink": "LINK-ID-CONTRATTO-TEST",
"tipologia_contratto": "ORDINE",
"presenza_AQ": false,
"identificativo_AQ_hyperlink": "LINK-AQ-TEST",
"accordo_quadro": 12,
"importo_contratto": 122000,
"residuo_AQ": 20000,
"compagine_di_AQ": "COMPAGINE-DI-AQ-TEST",
"quota_percentuale_di_RTI": 20,
"tipologia_di_partecipazione": "GARA PUBBLICA",
"cig": "CIG-TEST-3",
"cliente": "CLIENTE-TEST-3",
"vat_cliente": "XXX123",
"cliente_finale": "CLIENTE-FINALE-TEST-3",
"vat_cliente_finale": "YYY321",
"data_sottoscrizione_contratto": "8/12/2020",
"data_inizio_attivita": "8/28/2020",
"data_fine_attivita": "8/31/2020",
"stato_ordine": "CHIUSO"
}
}
]
}
正如您在此 JSON 文件中定义的对象中所见,commessa 字段以这种方式定义:
"commessa": {
"code": "AAA0002"
},
可能是错误的,也可能是其他地方的问题。
我错过了什么?为什么我收到此错误?我该如何尝试修复此错误?
您忘记使用 getter?
get comessaList()
{
return this.orderForm .get("comessaList") as FormArray
}
为避免初始错误,您可以使用 *ngIf
<div *ngIf="orderForm" [formGroup]="orderForm">
....
</div>
您在 html 中缺少 formArrayName div。
确保将 HTML 和 formArrayName="commessaList"
括起来
<div formArrayName="commessaList">
<div class="form-group row">
<label for="commessa" class="col-sm-2 col-form-label">Commessa</label>
<div class="col-sm-10">
<ng-container *ngFor="let commessa of commessaList.controls; index as idx">
................
................
</ng-container>
</div>
</div>
</div>
我正在做一个 Angular 项目,使用反应形式并引入 FormArray(因为我有一个字段被动态创建为多个字段的情况)我是面临以下问题。
基本上是一个定义我的 HTML 代码的表格我有这样的东西:
<div class="col-10">
<ng-container *ngFor="let commessa of commessaList.controls; index as idx">
<div class="row">
<div class="col-sm-8">
<input type="text" [ngClass]="{'error':commessa.invalid && commessa.touched}"
[formControlName]="idx"
class="form-control" id="commessa">
</div>
<div class="col-sm-2">
<button type="button" *ngIf="idx===0" (click)="addCommessaField()" class="btn btn-success"
[ngClass]="'pad'"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
<button (click)="deleteCommessaField(idx)" *ngIf="idx!==0" class="btn btn-danger">
<i class="fa fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</ng-container>
</div>
</div>
此部分用于定义我的表单的突出显示部分(我可以在其中添加多个“Commessa”字段:
然后在我的 TypeScript 代码中定义了 orderForm: FormGroup; 对象,我用它来定义表单字段和相关的验证规则,我将它设置到 ngOnInit() 方法:
ngOnInit() {
this.orderFormValues = new OrderFormValues();
console.log("orderFormValues VALUES: " + this.orderFormValues.statoOrdine);
this.orderForm = this.fb.group({
idOrdine: [null, [Validators.required]],
dataInserimentoOrdine: [new Date(), [Validators.required]],
statoOrdine: [null, [Validators.required, Validators.minLength(5)]],
//commessa: [null, [Validators.required, Validators.minLength(5)]],
commessaList: new FormArray([
new FormControl('', [Validators.required, Validators.minLength(5)])
]),
CIG: [null, [Validators.required, Validators.pattern("^[a-zA-Z0-9]{10}$")]],
dataInizioAttivita: [null, [Validators.required]],
dataFineAttivita: [null, [Validators.required]],
referente: [null, [Validators.required]],
ruoloReferente: [null, [Validators.required]],
tipologiaDiPartecipazione: [null, [Validators.required, Validators.minLength(5)]],
quotaPercentualeDiRTI: [null, [Validators.max(100)]],
cliente: [null, [Validators.required]],
vatCliente: [null, [Validators.required]],
clienteFinale: [null, []],
vatClienteFinale: [null, []],
tipologiaContratto: [null, []],
importoContratto: [null, [Validators.required]],
linkContratto: [null, [Validators.required]],
dataSottoscrizioneContratto: [null, [Validators.required]],
nomeSocieta: [null, [Validators.required]],
vatSocieta: [null, []],
buName: [null, [Validators.required]],
presenzaAQ: [false, [Validators.required]],
linkIdentificativoAQ: [null, []],
accordoQuadro: [null, []],
residuoAccordoQuadro: [null, []],
compagineDiAQ: [null, []]
});
this.ordersService.getAllOrders().then(orders => {
this.orders = orders;
console.log("RETRIEVED ORDERS: ", orders);
this.loading = false;
});
.........................................................................................
.........................................................................................
.........................................................................................
}
正如您在 FormGroup 定义中看到的,与多个“Commessa”字段相关的部分以这种方式定义为 FormArray :
commessaList: new FormArray([
new FormControl('', [Validators.required, Validators.minLength(5)])
]),
为了完整起见,我在我的 TypeScript 代码中添加了这两种方法,用于将用户插入的值插入多个 Commessa 字段中 FormArray 对象:
addCommessaField() {
this.commessaList.push(new FormControl('', [Validators.required, Validators.minLength(5)]));
}
deleteCommessaField(index: number) {
if (this.commessaList.length !== 1) {
this.commessaList.removeAt(index);
}
console.log(this.commessaList.length);
}
正如您在我的 ngOnInit() 方法中的前一个代码片段中所见,我也在执行对 OrderService 对象的调用:
this.ordersService.getAllOrders().then(orders => {
this.orders = orders;
console.log("RETRIEVED ORDERS: ", orders);
this.loading = false;
});
此调用只是检索显示在主页中的订单列表(目前模拟到 JSON 文件中),我在这里遇到一个奇怪的错误。
我的getAllOrders()服务方法的代码就是这个:
getAllOrders() {
return this.http.get<any>('assets/json_mock/ordini.json')
.toPromise()
.then(res => <Order[]>res.data)
.then(data => { return data; });
}
如您所见,它从 ordini.json 文件中检索和 return 订单。
问题是调用 getAllOrders() 服务方法它检索订单列表,但在 Chrome 控制台中我也收到此错误消息:
core.js:6228 ERROR Error: Cannot find control with name: '0'
at _throwError (forms.js:3576)
at setUpControl (forms.js:3398)
at FormGroupDirective.addControl (forms.js:7679)
at FormControlName._setUpControl (forms.js:8451)
at FormControlName.ngOnChanges (forms.js:8368)
at FormControlName.wrapOnChangesHook_inPreviousChangesStorage (core.js:26966)
at callHook (core.js:4730)
at callHooks (core.js:4690)
at executeInitAndCheckHooks (core.js:4630)
at selectIndexInternal (core.js:9748)
奇怪的是,它发生在我使用之前的 FormArray 实现这个多个“Commessa”字段之后(在我只有一个“Commessa”输入字段之前,我没有这个错误)。我怀疑错误可能出在我原来的 JSON 内容中,但我不明白为什么以及如何解决这个问题。
按照我的 ordini.json 文件的内容:
{
"data": [
{
"id": 1,
"referente": {
"name": "Mario",
"surname": "Rossi",
"complete_name": "Mario Rossi",
"role": "Operation Manager",
"avatar": "mario-rossi.jpg"
},
"company": {
"name": "TEST S.p.A.",
"VAT": "IT 03318271214",
"BU": {
"name": "Digital Solution",
"code": "DS"
}
},
"dettaglio_ordine": {
"data_inserimento": "08/08/2020",
"commessa": {
"code": "AAA0001"
},
"identificativo_contratto_hyperlink": "LINK-ID-CONTRATTO-TEST",
"tipologia_contratto": "ORDINE",
"presenza_AQ": true,
"identificativo_AQ_hyperlink": "LINK-AQ-TEST",
"accordo_quadro": 12,
"importo_contratto": 122000,
"residuo_AQ": 20000,
"compagine_di_AQ": "COMPAGINE-DI-AQ-TEST",
"quota_percentuale_di_RTI": 20,
"tipologia_di_partecipazione": "GARA PUBBLICA",
"cig": "CIG-TEST-1",
"cliente": "CLIENTE-TEST-1",
"vat_cliente": "VAT-CLIENTE",
"cliente_finale": "CLIENTE-FINALE-TEST-1",
"vat_cliente_finale": "VAT-CLIENTE-FINALE",
"data_sottoscrizione_contratto": "8/12/2020",
"data_inizio_attivita": "8/28/2020",
"data_fine_attivita": "8/31/2020",
"stato_ordine": "CHIUSO"
}
},
{
"id": 2,
"referente": {
"name": "Mario",
"surname": "Rossi",
"complete_name": "Mario Rossi",
"role": "Operation Manager",
"avatar": "mario-rossi.jpg"
},
"company": {
"name": "Blabla S.p.A.",
"VAT": "IT 03318271214",
"BU": {
"name": "Cyber Security",
"code": "CS"
}
},
"dettaglio_ordine": {
"data_inserimento": "09/08/2020",
"commessa": {
"code": "AAA0002"
},
"identificativo_contratto_hyperlink": "LINK-ID-CONTRATTO-TEST",
"tipologia_contratto": "ORDINE",
"presenza_AQ": false,
"identificativo_AQ_hyperlink": "LINK-AQ-TEST",
"accordo_quadro": 12,
"importo_contratto": 122000,
"residuo_AQ": 20000,
"compagine_di_AQ": "COMPAGINE-DI-AQ-TEST",
"quota_percentuale_di_RTI": 20,
"tipologia_di_partecipazione": "GARA PUBBLICA",
"cig": "CIG-TEST-2",
"cliente": "CLIENTE-TEST-1",
"vat_cliente": "VAT CLIENTE TEST",
"cliente_finale": "CLIENTE-FINALE-TEST-2",
"vat_cliente_finale": "VAT-CLIENTE-FINALE-TEST",
"data_sottoscrizione_contratto": "8/12/2020",
"data_inizio_attivita": "8/28/2020",
"data_fine_attivita": "8/31/2020",
"stato_ordine": "CHIUSO"
}
},
{
"id": 3,
"referente": {
"name": "Francesco Nicola",
"surname": "Romano",
"complete_name": "Francesco Verdi",
"role": "Operation Manager",
"avatar": "francesco-romano.jpg"
},
"company": {
"name": "Blabla S.p.A.",
"VAT": "IT 03318271214",
"BU": {
"name": "Cyber Security",
"code": "CS"
}
},
"dettaglio_ordine": {
"data_inserimento": "10/08/2020",
"commessa": {
"code": "AAA0002"
},
"identificativo_contratto_hyperlink": "LINK-ID-CONTRATTO-TEST",
"tipologia_contratto": "ORDINE",
"presenza_AQ": false,
"identificativo_AQ_hyperlink": "LINK-AQ-TEST",
"accordo_quadro": 12,
"importo_contratto": 122000,
"residuo_AQ": 20000,
"compagine_di_AQ": "COMPAGINE-DI-AQ-TEST",
"quota_percentuale_di_RTI": 20,
"tipologia_di_partecipazione": "GARA PUBBLICA",
"cig": "CIG-TEST-3",
"cliente": "CLIENTE-TEST-3",
"vat_cliente": "XXX123",
"cliente_finale": "CLIENTE-FINALE-TEST-3",
"vat_cliente_finale": "YYY321",
"data_sottoscrizione_contratto": "8/12/2020",
"data_inizio_attivita": "8/28/2020",
"data_fine_attivita": "8/31/2020",
"stato_ordine": "CHIUSO"
}
}
]
}
正如您在此 JSON 文件中定义的对象中所见,commessa 字段以这种方式定义:
"commessa": {
"code": "AAA0002"
},
可能是错误的,也可能是其他地方的问题。
我错过了什么?为什么我收到此错误?我该如何尝试修复此错误?
您忘记使用 getter?
get comessaList()
{
return this.orderForm .get("comessaList") as FormArray
}
为避免初始错误,您可以使用 *ngIf
<div *ngIf="orderForm" [formGroup]="orderForm">
....
</div>
您在 html 中缺少 formArrayName div。
确保将 HTML 和 formArrayName="commessaList"
括起来<div formArrayName="commessaList">
<div class="form-group row">
<label for="commessa" class="col-sm-2 col-form-label">Commessa</label>
<div class="col-sm-10">
<ng-container *ngFor="let commessa of commessaList.controls; index as idx">
................
................
</ng-container>
</div>
</div>
</div>