haw*_*kus 34 strong-typing angular angular14
我只是在玩新的角度类型表单 api,不知道如何输入FormGroup在不声明特定“FormInterface”女巫必须与原始界面相匹配的情况下进行键入。
也许我错过了一些东西,或者根本不可能这样做。
我能够使事情正常工作(下面的示例),但我不喜欢这里的UserForm接口声明,它没有对User接口的引用,并且必须是它的镜像副本,但带有FormControl<>字段。
在这种情况下是否可以FormGroup仅使用User界面进行输入?
stackblitz上提供完整的工作示例
用户模型.ts
export interface User {
firstName: string;
lastName: string;
email: string;
age: number | null;
}
Run Code Online (Sandbox Code Playgroud)
用户服务.ts
@Injectable()
export class UserService {
add(user: User): void {
console.log('Add user', user);
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序组件.ts
interface UserForm {
firstName: FormControl<string>;
lastName: FormControl<string>;
email: FormControl<string>;
age: FormControl<number | null>;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
form: FormGroup<UserForm>;
constructor(private userService: UserService) {}
ngOnInit(): void {
this.form = new FormGroup({
firstName: new FormControl<string>('', { nonNullable: true }),
lastName: new FormControl('', { nonNullable: true }),
email: new FormControl('', { nonNullable: true }),
age: new FormControl<number | null>(null),
});
}
submitForm(): void {
this.userService.add(this.form.getRawValue());
}
}
Run Code Online (Sandbox Code Playgroud)
Rco*_*rNY 34
我也遇到了这个问题,因为我总是分配我的FormGroup稍后时间,并且我对必须在每个声明中添加大量样板类型感到不高兴FormGroup。感觉就像我在重复自己,所以我最终所做的是创建一个运行良好的实用程序类型。
export type ModelFormGroup<T> = FormGroup<{
[K in keyof T]: FormControl<T[K]>;
}>;
Run Code Online (Sandbox Code Playgroud)
这使得我可以轻松地键入FormGroup我拥有的许多数据模型的声明。例如:
export interface UserModel {
email: string;
password: string;
}
// In a class...
userFormGroup: ModelFormGroup<UserModel>;
ngOnInit() {
this.userFormGroup = this._formBuilder.nonNullable.group({
email: [''],
password: [''],
});
}
Run Code Online (Sandbox Code Playgroud)
很多时候,我的数据模型拥有的属性比我希望表单拥有的属性多,因此我利用TypeScript 的实用程序类型 、、、Pick等等...RequiredOmit
export interface UserModel {
email: string;
password: string;
dateAdded: Date;
dateUpdated: Date;
}
// In a class...
userFormGroup: ModelFormGroup<Pick<UserModel, 'email' | 'password' >>;
ngOnInit() {
this.userFormGroup = this._formBuilder.nonNullable.group({
email: [''],
password: [''],
});
}
Run Code Online (Sandbox Code Playgroud)
小智 6
我建议定义您的 FormGroup 并User从中推断接口。使用以下实用程序类型可以为您提供帮助。
export type FormValue<T extends AbstractControl> = T extends AbstractControl<infer TValue, any> ? TValue : never;
export type FormRawValue<T extends AbstractControl> = T extends AbstractControl<any, infer TRawValue> ? TRawValue : never;
Run Code Online (Sandbox Code Playgroud)
请注意,该FormValue类型将使所有属性成为可选,因为可以禁用控件。如果您自己不禁用控件或将可禁用控件标记为可选,则该FormRawValue类型将为您提供更多帮助。对于您的情况,请使用后者。
interface UserFormControls {
firstName: FormControl<string>;
lastName: FormControl<string>;
email: FormControl<string>;
age: FormControl<number | null>;
}
export type UserForm = FormGroup<UserFormControls>;
export type User = FormRawValue<UserForm>;
// type User = {
// firstName: string;
// lastName: string;
// email: string;
// age: number | null;
// }
Run Code Online (Sandbox Code Playgroud)
您可以尝试对表单变量使用明确的赋值。下面是代码:
form!: FormGroup;
Run Code Online (Sandbox Code Playgroud)
您还可以使用声明来初始化表单控件,因为您正在表单上“发布”值但尚未更新。
form: FormGroup = new FormGroup({
firstName: new FormControl<string>('', { nonNullable: true }),
lastName: new FormControl('', { nonNullable: true }),
email: new FormControl('', { nonNullable: true }),
age: new FormControl<number | null>(null),
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16445 次 |
| 最近记录: |