based on the comments, it sounds like you want a dynamic form based on a model... there is no "out of the box" solution to do this. You can write your own form model:
interface MyFormModelField {
initial?: {
value: any,
disabled: boolean
},
controlOptions?: AbstractControlOptions
// anything you find useful really?
}
export type MyFormModel<T> = Record<keyof T, MyFormModelField>
then implement it like so:
const USER_FORM_MODEL: MyFormModel<UserFormDetails> = {
Id: { },
agentCode: {
initial: {
value: '',
disabled: true
},
controlOptions: {
validators: Validators.required
}
},
userName: { },
firstName: { },
middleName: { },
lastName: { },
department: { },
}
then you could write a service for producing form groups based on an instance of the form model...
@Injectable({providedIn: 'root'})
export class MyFormBuilder {
constructor(private: fb) { }
buildForm<T>(formModel: MyFormModel<T>) {
const fg = Object.keys(formModel).reduce((grp, k) => {
const fld = formModel[k];
return Object.assign(grp, {
[k]: [fld.initial || '', fld.controlOptions]
})
}, {});
return this.fb.group(fg);
}
}
now, anytime you make changes to the UserFormDetails interface, typescript will yell at you to update the corresponding form model with the field information... and while updates won't flow "automatically" from a model update, you at least have some type safety in your forms. I'd personally stop here.
This next part isn't perfect, and I'm not a fan of it, but if you really want the next step to have it be more or less automatic from the class definition, you could write a function to build a default form model from a class, like this:
function buildDefaultFormModel<T>(model: new () => T) {
return Object.keys(new model()).reduce((form, k) => {
return Object.assign(form, {[k]: {}})
}, {} as MyFormModel<T>)
}
this requires 2 things, 1, the class your building a form for MUST have a default specified for each field, fields without defaults wont't be included. (This introduces a hidden dependency on fields having default values, which is why I don't like this method, however, you CAN configure ts to yell at you if you write a class that has properties without defaults or constructor assignments):
class UserFormDetails {
Id: number = 0;
agentCode: number = 0;
userName: string = '';
firstName: string = '';
middleName: string = '';
lastName: string = '';
department: string = '';
}
2, the object constructor must take no parameters. but TS will yell at you if you try to misuse it in this case.
the function could be used like this:
const USER_FORM_MODEL: MyFormModel<UserFormDetails> = {
...buildDefaultFormModel(UserFormDetails),
...{
agentCode: {
initial: {
value: '',
disabled: true
},
controlOptions: {
validators: Validators.required
}
},
}
}
this way you can use default fields, and also provide an override for specific fields.
finally, you could also leverage this form model to build a template, but that's a bigger task.
here's a blitz with this all implemented (and I went ahead and cleaned up the controller code): https://stackblitz.com/edit/github-ck3u8u-qtnasc?file=src%2Fapp%2Fuser-table%2Fuser-table.validators.ts