You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/// <summary>/// Base class of company and person/// </summary>[DataContract(Namespace = Constants.DataNamespace)]publicclassEntity{publicEntity(){Addresses=newList<Address>();}[DataMember]publicGuid?Id{get;set;}/// <summary>/// Name of the entity./// </summary>[DataMember(IsRequired =true)]//MVC and Web API does not care[System.ComponentModel.DataAnnotations.Required]//MVC and Web API care about only this[MinLength(2),MaxLength(255)]publicstringName{get;set;}/// <summary>/// Multiple addresses/// </summary>[DataMember]publicIList<Address> Addresses {get;set;}[DataMember]publicvirtualObservableCollection<PhoneNumber> PhoneNumbers {get;set;}publicoverridestringToString(){returnName;}[DataMember]publicUriWeb{get;set;}[DataMember,EmailAddress,MaxLength(255)]publicstringEmailAddress{get;set;}}[DataContract(Namespace = Constants.DataNamespace)]publicclassPerson:Entity{[DataMember]publicstringSurname{get;set;}[DataMember]publicstringGivenName{get;set;}/// <summary>/// Date of Birth./// This is optional./// </summary>[DataMember]publicDateOnly?DOB{get;set;}[DataMember][DataType(DataType.Date)]publicDateTimeOffset?Baptised{get;set;}publicoverridestringToString(){returnSurname+", "+GivenName;}}
Typed FormGroups generated
exportinterfacePersonextendsDemoWebApi_DemoData_Base_Client.Entity{/** Data type: Date */baptised?: Date|null;/** * Date of Birth. * This is optional. */dob?: Date|null;givenName?: string|null;surname?: string|null;}exportinterfacePersonFormPropertiesextendsDemoWebApi_DemoData_Base_Client.EntityFormProperties{/** Data type: Date */
baptised: FormControl<Date|null|undefined>,/** * Date of Birth. * This is optional. */dob: FormControl<Date|null|undefined>,givenName: FormControl<string|null|undefined>,surname: FormControl<string|null|undefined>,}exportfunctionCreatePersonFormGroup(){returnnewFormGroup<PersonFormProperties>({emailAddress: newFormControl<string|null|undefined>(undefined,[Validators.email,Validators.maxLength(255)]),id: newFormControl<string|null|undefined>(undefined),name: newFormControl<string|null|undefined>(undefined,[Validators.required,Validators.minLength(2),Validators.maxLength(255)]),web: newFormControl<string|null|undefined>(undefined),baptised: newFormControl<Date|null|undefined>(undefined),dob: newFormControl<Date|null|undefined>(undefined),givenName: newFormControl<string|null|undefined>(undefined),surname: newFormControl<string|null|undefined>(undefined),});}
There are some limitations in such code generation for type FormGrooup:
Generic types not supported, because FormGroup takes only concrete types.
(Nested) member fields of complex types not supported because of various reasons.
Proposed solution
Directive in Angular is similar to attribute in C#. Attributes in C# is used by .NET run time, and directive is used by Angular compiler. I would purpose such solution with some pseudo directives.
export interfaceEntity{/** * Multiple addresses */addresses?: Array<DemoWebApi_DemoData_Client.Address>|null;/** Max length: 255 */
@validation([Validators.email,Validators.maxLength(255)])emailAddress?: string|null;id?: string|null;/** * Name of the entity. * Required * Min length: 2 * Max length: 255 */
@validation('Super Hero',[Validators.required,Validators.minLength(2),Validators.maxLength(255)])
name: string;phoneNumbers?: Array<DemoWebApi_DemoData_Client.PhoneNumber>|null;web?: string|null;}
Sometimes a nested complex object like "addresses" is to be included in the FormGroup, then a directive like @formGroup(1) or @formArray() could decorate a respective member field.
The reason why @formGroup() has a number parameter is to avoid endless recursive nesting.
Alternatives considered
If such feature is implemented, WebApiClientGen just need to exporting respective directives according to C# attributes.
An alternative design is to have a declarative object to associated a data model/interface with a validation map, mapping some member fields with some validations. However, such approach may look almost the same as the current way, and require a lot more design change in Angular compiler. And this is not friendly to code generators like WebApiClientGen
Remarks:
Comparing with #46864, this proposal emphasizes on validations through declarative attributes (.NET) and directives (Angular), and cover more scenarios of application programming.
The text was updated successfully, but these errors were encountered:
Extending from the OP, the some validators may have an extra parameter to tell the compiler whether to inject some HTML attributes to , for example, maxlength, type email etc.
So the app will have both UI constraints and code level validations.
Remarks
Since a typed FormGroup generally is created in the constructor, and is assigned to a read only member field of the component which can be assigned only inside the constructor, the compiler should have enough info to process.
Noted that the code gen skips the properties of complex types and array type. However, it is easy to compose a FormGroup with nested Form Groups and nested Form Arrays. For example:
Therefore, the requested feature may take similar approach: skip complex property and array property, and let application programmers decide whether to include them in the nested Form Groups and Form Arrays in a Form Group.
Since generated typed forms from Swagger / OpenAPI definitions and ASP.NET Web API had been implemented, it shall be nicer that the Angular team could accelerate the development of generating type forms for client only data.
Which @angular/* package(s) are relevant/related to the feature request?
compiler-cli, compiler
Description
"As of Angular 14, reactive forms are strictly typed by default.", however, constructing typed FormGroup in TypeScript codes is still almost always a manual process.
It can bring productivity to application programming that Angular compiler can generate a typed FormGroup from declarative info of validations.
And such design concept is illustrated in WebApiCoreNG2FormGroupClientAuto.ts generated by WebApiClientGen according to declarative info of data constraints in C#.
Declarative info of data constraints in C#
Typed FormGroups generated
There are some limitations in such code generation for type FormGrooup:
Proposed solution
Directive in Angular is similar to attribute in C#. Attributes in C# is used by .NET run time, and directive is used by Angular compiler. I would purpose such solution with some pseudo directives.
Application codes:
NG compiler or its pre-processor or IDE generates
Sometimes a nested complex object like "addresses" is to be included in the FormGroup, then a directive like
@formGroup(1)
or@formArray()
could decorate a respective member field.The reason why
@formGroup()
has a number parameter is to avoid endless recursive nesting.Alternatives considered
If such feature is implemented, WebApiClientGen just need to exporting respective directives according to C# attributes.
An alternative design is to have a declarative object to associated a data model/interface with a validation map, mapping some member fields with some validations. However, such approach may look almost the same as the current way, and require a lot more design change in Angular compiler. And this is not friendly to code generators like WebApiClientGen
Remarks:
Comparing with #46864, this proposal emphasizes on validations through declarative attributes (.NET) and directives (Angular), and cover more scenarios of application programming.
The text was updated successfully, but these errors were encountered: