改善引脚输入组件

时间:2019-04-05 15:58:04

标签: javascript angular

我有一个包含四个只能输入数字的输入字段的组件。输入后,焦点将从当前输入字段跳转到下一个输入字段。删除也可以(按Backspace键)-删除当前字段中的值会将焦点移到前一个。

我的问题是当前的实现是静态的,这意味着某些值是硬编码的。如果您查看at this demo,将会看到每个(input)事件都发送一个硬编码的索引。每个(delete)都一样。

另一个限制是,如果要添加第五个输入,则需要复制一个现有输入并进行一些调整。

所以我的挑战正确地知道了如何使它变得更加动态和灵活。就像指定应该有多少输入。另外,不要对索引进行硬编码,但可以从代码中找出来。

关于如何做到这一点的任何建议?

2 个答案:

答案 0 :(得分:3)

在此示例中,我使用的是反应形式。我会将其作为一个单独的组件,然后将数字位数传递给该组件,然后由该组件处理其他所有内容。您可能需要将数字传递给父组件,并且可以使用@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))
  }
}

然后处理事件并检查有效数字,更改对字段的关注程度等,这些是在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');
    }
  }
}

然后在模板中,我们将迭代表单数组,然后完成!

<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>

仅此一个组件就不容易使用

<hello [numOfDigits]="4"></hello>

DEMO

答案 1 :(得分:0)

您正在寻找fetch(fetchableUrl, { method: "GET", headers: { api_key: "somekey", "Content-Type": "application/json" } }) .then(response => response.json()) .then(restData => { dispatch({ type: FETCH_REST, payload: restData }); }) .catch(error => { console.error(error); }); 指令的内容。 参见:https://angular.io/guide/displaying-data#showing-an-array-property-with-ngfor

我也分叉了您的示例并对其进行了修改: https://stackblitz.com/edit/angular-ug7b69?file=src%2Fapp%2Fapp.component.html

但是,您将在*ngFor的方法中遇到其他问题,您将在示例中很快注意到。我建议研究一下@HostListener指令和/或Angular Forms(ngModelFormGroup等),以找到一种更安全的方法来检测这些输入更改并对它们做出反应。