Angular 为什么表单控件以被动形式显示[对象][对象]?
我有Angular 为什么表单控件以被动形式显示[对象][对象]?,angular,reactive-forms,Angular,Reactive Forms,我有函数,可以动态创建反应式表单。我只需要通过feilds的array 以下是我的服务中的功能 createForm(fieldsArr: any[]) { let formObject = {}; fieldsArr.forEach(f => { if(f.isArray){ if(f.defaultValue === null){ formObject[f.name] = this.fb.array([]); } else {
函数
,可以动态创建反应式
表单。我只需要通过feilds
的array
以下是我的服务中的功能
createForm(fieldsArr: any[]) {
let formObject = {};
fieldsArr.forEach(f => {
if(f.isArray){
if(f.defaultValue === null){
formObject[f.name] = this.fb.array([]);
} else {
formObject[f.name] = this.fb.array([this.createArrayType(f.nestedFieldsArr)]);
}
} else {
formObject[f.name] = [f.defaultValue ? f.defaultValue : '', f.isRequired ? Validators.required : Validators.nullValidator];
}
})
return this.fb.group(formObject);
}
createArrayType(nestedFieldsArr: any[]) {
let nestedFormObj = {};
nestedFieldsArr.forEach(f => {
nestedFormObj[f.name] = [[{ value: f.defaultValue ? f.defaultValue : '', disabled: f.isDisabled ? true : false }], f.isRequired ? Validators.required : Validators.nullValidator]
})
let form = this.fb.group(nestedFormObj);
return form;
}
这是字段的数组
,我将其传递给我的函数
以创建反应式表单
public marketPlaceFormFields = [
{
name: 'pickupLocations',
isRequired: true,
isArray: true,
nestedFieldsArr: [
{
name: 'location',
isRequired: true
},
{
name: 'lat',
isRequired: false
},
{
name: 'long',
isRequired: false
},
{
name: 'locationCode',
isRequired: false,
},
{
name: 'dateTime',
isRequired: true
}
]
},
{
name: 'deliveryLocations',
isRequired: true,
isArray: true,
nestedFieldsArr: [
{
name: 'location',
isRequired: true
},
{
name: 'lat',
isRequired: false
},
{
name: 'long',
isRequired: false
},
{
name: 'locationCode',
isRequired: false
},
{
name: 'dateTime',
isRequired: true
}
]
},
{
name: 'waypoints',
isRequired: true,
isArray: true,
defaultValue: null,
nestedFieldsArr: [
{
name: 'location',
isRequired: true
},
{
name: 'lat',
isRequired: false
},
{
name: 'long',
isRequired: false
},
{
name: 'locationCode',
isRequired: false
},
{
name: 'type',
isRequired: false
},
{
name: 'dateTime',
isRequired: true
}
]
},
{
name: 'bidVehicles',
isRequired: true,
isArray: true,
nestedFieldsArr: [
{
name: 'vehicleLoadId',
isRequired: false,
defaultValue: 0
},
{
name: 'categoryId',
isRequired: true
},
{
name: 'numberOfVehicles',
isRequired: true
},
{
name: 'loadRequirementId',
isRequired: false,
defaultValue: 1
}
]
},
{
name: 'shipmentWeight',
isRequired: true
},
{
name: 'budgetMin',
isRequired: true
},
{
name: 'budgetMax',
isRequired: true
},
{
name: 'paymentTerm',
isRequired: false,
defaultValue: 'Cash on Delivery'
},
{
name: 'bidDateFrom',
isRequired: true
},
{
name: 'bidDateTo',
isRequired: true
},
{
name: 'orderId',
isRequired: false
},
{
name: 'insertedBy',
isRequired: false
},
{
name: 'shipperId',
isRequired: false
}
];
component.ts
get pickLocatons() { return this.frm.pickupLocations as FormArray; }
ngOnInit(){
this.marketForm = this.us.createForm(this.constants.marketPlaceFormFields);
}
component.html
<ng-container *ngFor="let pickControl of pickLocatons.controls; let i = index">
<div class="row" [formGroup]="pickControl">
<div class="col-md-3">
<div class="form-group">
<label>
Pick up Location
<span class="text-danger font-bold ml-1">*</span>
<i class="fa fa-info-circle ml-1 color-primary cursor-pointer" placement="auto"
ngbPopover="{{constants.popovers.bid.pickup}}" popoverClass="op-popover"></i>
</label>
<div class="input-group">
<input type="text" class="form-control" placeholder="Bazar Kharadan, Koh..." formControlName="location" [ngClass]="{'is-invalid' : pickControl.get('location')?.errors &&
(pickControl.get('location').touched || pickControl.get('location').dirty)}" />
<div class="input-group-append cursor-pointer" (click)="openMapModal('pickupLoc', i)">
<span class="input-group-text"><i class="fa fa-map-marker px-1"></i></span>
</div>
</div>
<span class="help-block" *ngIf="pickControl.get('location')?.errors &&
(pickControl.get('location').touched || pickControl.get('location').dirty)">
<span *ngIf="pickControl.get('location')?.errors?.required" class="text-danger">
{{constants.errors.required.location}}
</span>
</span>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>
<!-- <i class="fa fa-map-marker color-primary" aria-hidden="true"></i> -->
Add Corresponding Code
<i class="fa fa-info-circle ml-1 color-primary cursor-pointer" placement="auto"
ngbPopover="{{constants.popovers.bid.code}}" popoverClass="op-popover"></i>
</label>
<input type="text" class="form-control" placeholder="Code" formControlName="locationCode" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>
<!-- <i class="fa fa-calendar-o color-primary" aria-hidden="true"></i> -->
Date/Time
<span class="text-danger font-bold ml-1">*</span>
<i class="fa fa-info-circle ml-1 color-primary cursor-pointer" placement="auto"
ngbPopover="{{constants.popovers.bid.picDate}}" popoverClass="op-popover"></i>
</label>
<input type="datetime-local" class="form-control" formControlName="dateTime" min="{{ (minDate | date: 'yyyy-MM-dd') + 'T00:00' }}" [max]="eConfig.DATETIME_MAX" [ngClass]="{'is-invalid' : pickControl.get('dateTime')?.errors &&
(pickControl.get('dateTime').touched || pickControl.get('dateTime').dirty)}">
<span class="help-block" *ngIf="pickControl.get('dateTime')?.errors &&
(pickControl.get('dateTime').touched || pickControl.get('dateTime').dirty)">
<span *ngIf="pickControl.get('dateTime')?.errors?.required" class="text-danger">
This is required
</span>
</span>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<button class="btn btn-primary rounded-0 mt-28" (click)="addLocation()" *ngIf="i === 0">+ Add Stop</button>
<button class="btn btn-primary rounded-0 mt-28" (click)="removeLocation(i)" *ngIf="i > 0">+ Remove</button>
</div>
</div>
取货地点
*
{{constants.errors.required.location}
添加相应的代码
日期/时间
*
这是必需的
+加站
+除去
但问题是,当页面加载时,表单数组字段将[object][object]显示为这样的输入值
我不知道为什么表单字段在页面加载后显示[object][object]
注意:我在帖子中只包含了必要的代码。据我所知,您有一个FormGroup,其中包含一个FormArray,其中包含一个列表,其中包含一个FormGroup,其中包含您的FormControls。在HTML中,您需要一个FormGroup,其中包含FormArray,包含FormControl列表。所以看起来你在HTML中嵌套的太多了,或者没有足够的去加成。从您的评论来看,您似乎需要FormArray,因此这里有一个更新的解决方案:
createForm(fieldsArr: any[]) {
const formGroup = new FormGroup({});
fieldsArr.forEach(f => {
if(f.isArray){
if(f.defaultValue === null){
// seems to never happen ? because you would need 1 default value for each element of your array, not just one defaultValue.
// formObject[f.name] = this.fb.array([]);
} else {
formGroup.addControl(f.name, this.createNestedFormArray(f.nestedFieldsArr)); // removed the FormArray layer
}
} else {
const formControl = new FormControl(f.defaultValue ? f.defaultValue : '',
f.isRequired ? Validators.required : Validators.nullValidator);
formGroup.addControl(f.name, formControl);
// formObject[f.name] = [f.defaultValue ? f.defaultValue : '', f.isRequired ? Validators.required : Validators.nullValidator];
}
});
return formGroup;
}
createNestedFormArray(nestedFieldsArr: any[]) {
const nestedFormGroup = new FormGroup({});
nestedFieldsArr.forEach(f => {
const formControl = new FormControl(f.defaultValue ? f.defaultValue : '',
f.isRequired ? Validators.required : Validators.nullValidator);
if ( f.isDisabled ) {
formControl.disable(); // moved disabled logic from constructor (not valid)
}
nestedFormGroup.addControl(f.name, formControl);
// nestedFormObj[f.name] = [[{ value: f.defaultValue ? f.defaultValue : '', disabled: f.isDisabled ? true : false }], f.isRequired ? Validators.required : Validators.nullValidator]
})
return new FormArray([nestedFormGroup]);
}
在HTML中,在FormArray上循环:
<ng-container *ngFor="let pickArray of pickLocatons.controls">
<!-- pickArray is the FormArray, containing multiple FormGroups -->
<ng-container *ngFor="let pickNestedGroup of pickArray; let i = index" [formGroupName]="i">
<!-- pickNestedGroup is the FormGroup, containing multiple FormControls (location, lat, long...) -->
<!-- [formGroupName]="i" means you are using the ith element of the FormArray as reference for every following formControlNames, instead of the parent one -->
<input formControlName="location"/>
因为您在单个输入中设置了FormArray。。。您必须循环您的formArray,以便为formArray的每个项目设置1个输入…但是如果您看到我的ng容器
,那么我将循环我的formArray
,并将单个formgroup控件绑定到输入。您的表单初始化非常混乱。。。您应该使用if/else而不是嵌套的三元代码。在我看来,您在FormArray中注入了一个FormGroup(由createArrayType
返回)。您的FormArray应该包含FormControls,而不是FormGroups,据我从您的代码中了解……您能通过操纵一点代码来正确回答这个问题吗?您能先将您的三元代码转换为if/else语句吗?但我想要多个收货和发货位置的表单组。因为用户可以添加多个收货和发货位置。好的,所以您可以使用单个元素初始化FormArray,但是用户可以添加一个,对吗?所以你必须在HTML中循环使用FormArray,我会更新答案谢谢,你的答案帮助了我。我根据我的需要修改了你的代码:)刚刚更新,包括FormArray