Dzh*_*hev 3 javascript angular
我有一个带有四个输入字段的组件,只能输入数字。输入后,焦点从当前输入字段跳到下一个输入字段。删除也有效(当按下退格键时) - 删除当前字段中的值会将焦点移至上一个字段。
我遇到的问题是当前的实现非常静态,这意味着某些值是硬编码的。如果您查看此演示,您将看到每个(input)事件都会发送一个硬编码索引。每个都一样(delete)。
另一个限制是,如果我想添加第五个输入,我需要复制现有输入之一并进行一些调整。
因此,我所面临的挑战是如何使其更加动态和灵活。就像指定应该有多少个输入一样。也不要对索引进行硬编码,但能够从代码中找出答案。
关于如何做到这一点有什么建议吗?
在此示例中,我使用的是反应式形式。我会将其作为一个单独的组件,您只需将位数传递给该组件,然后该组件就会处理其他所有事情。您可能需要将数字传递给父组件,然后您就可以使用@Output它。您不需要创建一个组件,但为了干净起见,我会创建一个组件:)
因此,我们可以创建一个HelloComponent(刚刚从 stackblitz 模板获得的名称),我们将在其中构建表单,将尽可能多的表单控件推送到您指定的数组中:
@Input() numOfDigits;
@ViewChildren('inputs') inputs: QueryList<any>;
confirmCodeForm: FormGroup;
constructor(private fb: FormBuilder) {
this.confirmCodeForm = this.fb.group({
digits: this.fb.array([]) // create empty form initially
});
}
ngOnInit() {
// push form controls to the formarray
for (let i = 0; i< this.numOfDigits; i++) {
(this.confirmCodeForm.get('digits') as FormArray).push(this.fb.control(null))
}
}
Run Code Online (Sandbox Code Playgroud)
然后处理事件并检查有效数字,将焦点更改为字段等,这些事件会被触发keydown:
check(index, field, event) {
if (isNaN(parseInt(event.key, 10)) && event.key !== 'Backspace') {
event.preventDefault();
}
else if (field.value && event.key !== 'Backspace') {
if (index < this.inputs.toArray().length - 1) {
this.inputs.toArray()[index + 1].nativeElement.focus();
}
}
else if (event.key === 'Backspace') {
if (index > 0) {
field.setValue(null)
this.inputs.toArray()[index - 1].nativeElement.focus();
} else {
console.log('first field');
}
}
}
Run Code Online (Sandbox Code Playgroud)
在模板中,我们将迭代表单数组,然后就完成了!
<form (ngSubmit)="confirmCode(confirmCodeForm.value)" [formGroup]="confirmCodeForm">
<div formArrayName="digits">
<input *ngFor="let field of confirmCodeForm.get('digits').controls;
let i = index"
#inputs
[maxLength]="1"
[formControlName]="i"
(keydown)="check(i, field, $event)">
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
不,这个组件很容易使用,只需
<hello [numOfDigits]="4"></hello>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1548 次 |
| 最近记录: |