如何在应用程序中为Angular Forms制作带有表单控件输入的通用组件 [英] How to make generic component with form control input for Angular Forms in app

查看:35
本文介绍了如何在应用程序中为Angular Forms制作带有表单控件输入的通用组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为 datepicker 创建了组件,我想在我的应用程序的许多其他组件中使用它.我有一些问题,因为它不会改变父表单组控件的值.

让我们进入代码:

导出类 DatePickerComponent {@ViewChild('input', {read: ElementRef, static: false}) inputRef: ElementRef;@输入()表格名称?:表格组;@输入()表单控件名称:任意;构造函数(){this.formControlName.setValue(['']);}onKeyPress = (事件) =>{const pressKey = event.keyCode;如果 (pressKey !== 8 &&pressKey !== 9 &&pressKey !== 13 &&((pressedKey < 48 ||pressedKey > 105) || (pressedKey > 57 &&pressedKey < 96))){event.preventDefault();}}onKeyUp = (事件) =>{const pressKey = event.keyCode;const inputString: string = this.formControlName.value;如果(!输入字符串){返回;}if (inputString.length === 11) {this.inputRef.nativeElement.value = inputString.slice(0, -1);返回;}if (pressedKey === 8 && (inputString.length === 3 || inputString.length === 6)) {const newValue = inputString.slice(0, -1);this.formControlName.setValue(newValue);this.inputRef.nativeElement.value = newValue;} else if (inputString.length === 2 || inputString.length === 5) {const newValue = inputString + '/';this.formControlName.setValue(newValue);this.inputRef.nativeElement.value = newValue;}}}

和模板:

<输入类=形式控制"formControlName="{{formControlName}}"占位符="DD/MM/YYYY"名称=dp"ngbDatepicker#d="ngbDatepicker"[minDate]="{年:1930,月:1,日:1}"(点击)="d.toggle()"(keydown)="onKeyPress($event)"(keyup)="onKeyUp($event)">

所以我想在 FormGroup 属性设置为 X 的父组件中使用它.要使用我添加的组件<app-date-picker [formControlName]="birthDate" [formName]="registerForm"></app-date-picker>

也许我在父组件中做错了什么:

导出类 UserFormComponent 实现 OnInit {@Input() isRegisterPage: boolean;@Input() isProfilePage: 布尔值;@Input() 用户:用户信息;注册表格:表格组;出生日期:FormControl;加载:布尔值;.e.t.C

如何使我的日期选择器可以正确重用?也许有人可以帮助我?

仅使用日期选择器(未在父表单中使用):https://stackblitz.com/edit/angular-i47zuz-jj5glk?file=app/datepicker-popup.ts

解决方案

你做错了!,为了让你的自定义组件像 FormControl 一样使用表单,你应该让它FormControl,为此,您需要实现 ControlValueAccessor 接口,因此您的组件将作为自定义 FormControl 工作,您可以在此处阅读如何操作 -> ControlValueAccessor,如果您在实施时遇到问题,请告诉我,我可以提供进一步的帮助,但请尝试先自己实现,学得更好

I've created component for datepicker that I want to use in many other components in my application. I have some problems becouse it doesn't change value of parent form group control.

Lets get to the code:

export class DatePickerComponent {
@ViewChild('input', {read: ElementRef, static: false}) inputRef: ElementRef;
@Input()
formName?: FormGroup;
@Input()
formControlName: any;

constructor() {
this.formControlName.setValue(['']);
}

onKeyPress = (event) => {
const pressedKey = event.keyCode;

if (
  pressedKey !== 8 &&
  pressedKey !== 9 &&
  pressedKey !== 13 &&
  ((pressedKey < 48 || pressedKey > 105) || (pressedKey > 57 && pressedKey < 96))
) {
  event.preventDefault();
}
}

onKeyUp = (event) => {
const pressedKey = event.keyCode;
const inputString: string = this.formControlName.value;

if (!inputString) {
  return;
}

if (inputString.length === 11) {
  this.inputRef.nativeElement.value = inputString.slice(0, -1);
  return;
}

if (pressedKey === 8 && (inputString.length === 3 || inputString.length === 6)) {
  const newValue = inputString.slice(0, -1);
  this.formControlName.setValue(newValue);
  this.inputRef.nativeElement.value = newValue;
} else if (inputString.length === 2 || inputString.length === 5) {
  const newValue = inputString + '/';
  this.formControlName.setValue(newValue);
  this.inputRef.nativeElement.value = newValue;
}
}

}

And the template:

<div [formGroup]="formName">
<input
class="form-control"
formControlName="{{formControlName}}"
placeholder="DD/MM/YYYY"
name="dp"
ngbDatepicker
#d="ngbDatepicker"
[minDate]="{year: 1930, month: 1, day: 1}"
(click)="d.toggle()"
(keydown)="onKeyPress($event)"
(keyup)="onKeyUp($event)">
</div>

So I wanted to use it in parent component that is form with FormGroup property set to X. To use my component I've added <app-date-picker [formControlName]="birthDate" [formName]="registerForm"></app-date-picker>

Maybe I did something wrong in parent component:

export class UserFormComponent implements OnInit {

@Input() isRegisterPage: boolean;
@Input() isProfilePage: boolean;
@Input() user: UserInfo;
registerForm: FormGroup;
birthDate: FormControl;
loading: boolean;
.e
.t
.c

How to make my datepicker reusable correctly? Maybe somone can help me?

Fiddle with only datepicker (not used in parent form): https://stackblitz.com/edit/angular-i47zuz-jj5glk?file=app/datepicker-popup.ts

解决方案

you are doing it wrong !, to make your custom component work with forms as FormControl you should make it FormControl, to do so, you need to implement ControlValueAccessor interface, so your component would work as custom FormControl, you can read how to do it here -> ControlValueAccessor, if you have problems on implementing it let me know, I can provide further help, but try to implement it on your own first, to learn better

这篇关于如何在应用程序中为Angular Forms制作带有表单控件输入的通用组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆