Angular,如何在FormArray的特定FormControl中设置焦点

时间:2018-11-21 13:37:37

标签: angular

我如何将焦点设置到formArray中的特定字段?

这是formArray:

    this.productForm = this.formBuilder.array([
     this.formBuilder.group({
     code: [null],
     description: [null],
     unitPrice: [null],
     qty: [null],
     discount: [null],
     vat: [null],
     total: [null],
     amount: [null],
     taxAmount: [null]
  })
]);

我可以拥有很多这个formGroup,并且需要关注特定的描述字段。 角度有聪明的方法吗?

3 个答案:

答案 0 :(得分:0)

如果您知道要关注的特定项目,那么首先通过添加模板参考就可以非常简单地完成

<input
  #fieldName
  type="text"
  id="fieldName"
  name="fieldName"
  formControlName="yourFieldName" />

然后在您的组件中(可能在ngAfterViewInit()方法中):

@ViewChild('fieldName') fieldName: ElementRef;

然后专注于您的元素:

this.fieldName.nativeElement.focus();

但是,这将容易受到XSS攻击

答案 1 :(得分:0)

您可能想在应用程序中使用angular2-focus软件包,以便从下面的位置进行一致的使用。您将能够在应用程序中的任何地方重用代码。

https://www.npmjs.com/package/angular2-focus

使用此软件包,您将能够集中所有输入元素,如下所示。

<input type="text" focus="true">

包含以下模块

import {NgModule, Component} from '@angular/core';
import {FocusModule} from 'angular2-focus';
@NgModule({
  imports: [FocusModule.forRoot()],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

答案 2 :(得分:0)

发生了同样的问题。我通过重新考虑实现来解决它。

我的情况是,我希望在使用情况出现标签(模糊)的最后一行时,专注于该行(第一个输入)。我已经实现了指令来处理模糊并专注于我的Row。

import { Directive, Input, Output, ElementRef, EventEmitter, HostListener, HostBinding } from '@angular/core';

@Directive({
  selector: '[focusedRow]'
})
export class RowDirective {
  static tabindex = 1;
  static currentFocus = null;

  private timer: any = null;

  @HostBinding('tabindex') public tabIndex: number = 0;

  @Input('formGroupName') public rowNumber: number;

  @Output('focus') public onFocus: EventEmitter<number> = new EventEmitter<number>();
  @Output('blur')  public onBlur: EventEmitter<number> = new EventEmitter<number>();

  constructor(private elm: ElementRef) {
    this.tabIndex = RowDirective.tabindex++;
  }

  @HostListener('focusin', ['$event'])
  public focusHandler(event: Event) {
    // When we're not the current focus.
    if (RowDirective.currentFocus !== this) {
      this.onFocus.emit(event);

      RowDirective.currentFocus = this;

    } else {
      // Stop our blur from happening since it's the same row
      if (this.timer) {
        window.clearTimeout(this.timer);
        this.timer = null;
      }
    }
  }
  @HostListener('focusout', ['$event'])
  public blurHandler(event: Event) {
    this.timer = window.setTimeout(() => {
      // If our row has changed, then we have blurred.
      this.onBlur.emit(event);

      // Clear if this is still listed as the Focused Row.
      if (RowDirective.currentFocus === this) {
        RowDirective.currentFocus = null;
      }
    }, 200);
  }
}

我所做的是,不是试图与Angular Form Group对抗,而是让我从Reactive Form中创建一个新Row并添加该行,因为Form row元素具有指令。 应用后,更好的解决方案是在指令初始化时仅将行(第一个输入)聚焦。

这是使用OnInit界面完成的。因此,对上面的代码进行了调整,使其包含了界面(以下更改);

import { Directive, Input, Output, OnInit, ElementRef, EventEmitter, HostListener, HostBinding } from '@angular/core';

@Directive({
  selector: '[focusedRow]'
})
export class RowDirective implements OnInit {
  ....

  ngOnInit() {
    // Focus on the first Form Element
    this.elm.nativeElement.querySelector('input').focus();
  }

  ....
}

因此,请创建上述指令,然后将该指令添加到“表单数组”元素中...

 <tr *ngFor="let entry of myForms.controls; let index=index" [formGroupName]="index" focusedRow (focus)="rowFocus(index)" (blur)="rowBlur(index)">

通过这种方式,每当创建一行时,它都会聚焦于第一个表单元素。

此解决方案的优点在于,当用户单击我的“添加新行”按钮时,该解决方案也将起作用,并且您在[表]行上会得到一些不错的“焦点”和“模糊”处理程序。 (顺便说一下,秘诀就是使用tabindex属性)

希望对您有所帮助。