我正在使用由 json 文件创建的动态反应形式。
问题 - 需要将选项值从 api 传递到 mat-select 字段。
在 json_fields.json 中,我们选择选项现在是静态的字段。
想要将选项的静态值更改为针对国家/地区下拉列表的基于服务的 API 响应。
代码 -
random.component.html
<dynamic-form [form_class]="'from_class'" [fields]="fieldData" (submit)="onSubmit($event)"></dynamic-form>
random.component.ts
import sampleData from '../../../../../json_file/json_fields.json';
ngOnInit(): void {
this.fieldData = sampleData;
}
json_fields.json
[
{
"title": "",
"body": [
{
"type": "select",
"label": "Country",
"name": "Country",
"value": "",
"options": ["country1", "country2"],
"field_class": "field-pd",
"col":"col-md-12 col-lg-12 col-12"
},
{
"col":"col-md-12 col-lg-12 col-12",
"type": "button",
"label": "submit",
"size": "large",
"button_class": "btn btn-save btn-block",
"extra_class": "mh-0"
}
]
}
]
select.component.ts
<mat-label>{{field.label}}
<span *ngIf="field.status">*</span>
</mat-label>
<mat-form-field [class]="field.field_class" [style.width.%]="100" [floatLabel]="'never'" [formGroup]="group" appearance="outline">
<mat-select class="select-wd" disableOptionCentering panelClass="myPanelClass"
matNativeControl [placeholder]="field.label" [errorStateMatcher]="matcher" [formControlName]="field.name">
<mat-option *ngFor="let item of field.options" [value]="item">{{item}}</mat-option>
</mat-select>
<ng-container *ngFor="let validation of field.validations;" ngProjectAs="mat-error">
<mat-error *ngIf="group.get(field.name).hasError(validation.name)">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
动态表格-
dynamic.component.ts
import {
Component, EventEmitter, Input, OnInit, Output,} from "@angular/core";
import {
FormGroup, FormBuilder, Validators, FormControl} from "@angular/forms";
import { SessionStorageService } from "@app/auth/services/session-storage.service";
import { ShareFormdataService } from "@app/shared/services/form-data/share-formdata.service";
@Component({
exportAs: "dynamicForm",
selector: "dynamic-form",
template: `
<form [class]="form_class" [formGroup]="form" (submit)="onSubmit($event)">
<ng-container *ngFor="let field of fields">
<ng-container *ngFor="let field of field.body" [class]="field.Col">
<ng-container
dynamicField
[field]="field"
[group]="form"
></ng-container>
</ng-container>
</ng-container>
</form>
`,
styleUrls: ['./dynamic.scss']
})
export class DynamicFormComponent implements OnInit {
@Input() fields: any[] = [];
@Input() form_class: string;
@Output() submit: EventEmitter<any> = new EventEmitter<any>();
form: FormGroup;
invalidFields: any[] = [];
get value() {
return this.form.value;
}
constructor(
private fb: FormBuilder,
private SmartFormdata: ShareFormdataService,
private sessionStorageSr: SessionStorageService
) {}
ngOnInit() {
this.form = this.createControl();
const executiondData = this.sessionStorageSr.get('execution');
if(executiondData === 'enabled') {
this.form.disable();
} else {
this.form.enable();
}
}
ngAfterViewInit(): void {
this.SmartFormdata.currentMessage.subscribe((message: any) => {
if (message.data === "submit") {
this.sumitFormData();
} else {
if (message.data === "patch") {
this.form.patchValue(message.value);
}
}
});
}
sumitFormData() {
if (this.form.valid) {
this.submit.emit(this.form.value);
} else {
this.validateAllFormFields(this.form);
this.findInvalidControls();
}
}
findInvalidControls() {
this.invalidFields = [];
const controls = this.form.controls;
for (const name in controls) {
if (controls[name].invalid) {
this.invalidFields.push(name.split("_").join(" "));
}
}
return this.invalidFields;
}
onSubmit(event: Event) {
event.preventDefault();
event.stopPropagation();
this.sumitFormData();
}
createControl() {
const group = this.fb.group({});
this.fields.forEach((field) => {
field.body.forEach((field) => {
if (field.type === "button") return;
if (field.type === "divider") return;
if (field.type === "title") return;
const control = this.fb.control(
field.value,
this.bindValidations(field.validations || [])
);
group.addControl(field.name, control);
});
});
return group;
}
bindValidations(validations: any) {
if (validations.length > 0) {
const validList = [];
validations.forEach(valid => {
switch (valid.name) {
case "required":
if(valid.required) {
validList.push(Validators.required);
}
break;
case "maxlength":
validList.push(Validators.maxLength(valid.maxLength));
break;
case "minlength":
validList.push(Validators.minLength(valid.minLength));
break;
case "max":
validList.push(Validators.max(valid.max));
break;
case "min":
validList.push(Validators.min(valid.min));
break;
case "email":
if(valid.email) {
validList.push(Validators.email);
}
break;
case "pattern":
switch (valid.pattern) {
case 'number':
validList.push(Validators.pattern("^[0-9]*$"));
break;
case 'string':
validList.push(Validators.pattern("[a-zA-Z ]"));
break;
case 'decimal':
validList.push(Validators.pattern("^[0-9][0-9]*([.][0-9]{1,9}|)$"))
break;
case 'alphanumeric':
validList.push(Validators.pattern("^([a-zA-Z0-9]+ )+[a-zA-Z0-9]+$|^[a-zA-Z0-9]*$"))
break;
case 'whitespace':
validList.push(Validators.pattern("^([a-zA-Z0-9!@{}~#%$&()-`'.+,/\"]+ )+[a-zA-Z0-9!@{}~#%$&()-`'.+,/\"]+$|^[a-zA-Z0-9!@{}~#%$&()-`'.+,/\"]*$"))
break;
default:
break;
}
break;
default:
break;
}
});
return Validators.compose(validList);
}
return null;
}
validateAllFormFields(formGroup: FormGroup) {
Object.keys(formGroup.controls).forEach((field) => {
const control = formGroup.get(field);
return !!(
control &&
control.invalid &&
(control.dirty || control.markAsTouched({ onlySelf: true }))
);
});
}
}