2016-12-16 60 views
2

我似乎不能够将焦点设置输入字段动态添加FormGroup:如何以编程方式将焦点设置到动态创建FormControl在Angular2

addNewRow(){ 
    (<FormArray>this.modalForm.get('group1')).push(this.makeNewRow()); 
    // here I would like to set a focus to the first input field 
    // say, it is named 'textField' 

    // but <FormControl> nor [<AbstractControl>][1] dont seem to provide 
    // either a method to set focus or to access the native element 
    // to act upon 
} 

如何设置聚焦到angular2 FormControl或AbstractControl?

回答

3

您不能设置为FormControlAbstractControl,因为它们不是DOM元素。你需要做的是有一个元素引用他们,不知何故,并且在那上面叫.focus()。您可以通过ViewChildren(其中API文档目前不存在,2016-12-16)实现此目的。

在你的组件类:

import { ElementRef, ViewChildren } from '@angular/core'; 

// ...imports and such 

class MyComponent { 
    // other variables 
    @ViewChildren('formRow') rows: ElementRef; 

    // ...other code 
    addNewRow() { 
     // other stuff for adding a row 
     this.rows.first().nativeElement.focus(); 
    } 
} 

如果你希望把重点放在最后一个孩子...... this.rows.last().nativeElement.focus()

而且在你的模板是这样的:

<div #formRow *ngFor="let row in rows"> 
    <!-- form row stuff --> 
</div> 

编辑:

我实际上发现一个人在做你想要的CodePen https://codepen.io/souldreamer/pen/QydMNG

+0

我认为这是'@ViewChildren( 'formRow')行:QueryList ;' –

1

这是安全的方法通过角

@Component({ 
    selector: 'my-comp', 
    template: ` 
    <input #myInput type="text" /> 
    <div> Some other content </div> 
    ` 
}) 
export class MyComp implements AfterViewInit { 
    @ViewChild('myInput') input: ElementRef; 

    constructor(private renderer: Renderer) {} 

    ngAfterViewInit() { 
    this.renderer.invokeElementMethod(this.input.nativeElement,  
    'focus'); 
    } 
} 
+2

真。尽管如此:Renderer已被弃用,现在的Renderer2没有'invokeElementMethod'方法。 – user776686

0

建议对于角5,结合所有上述答案如下:

组件相关的代码:

import { AfterViewInit, QueryList, ViewChildren, OnDestroy } from '@angular/core'; 
import { Subscription } from 'rxjs/Subscription'; 

// .. other imports 

export class MyComp implements AfterViewInit, OnDestroy { 
    @ViewChildren('input') rows: QueryList<any>; 
    private sub1:Subscription = new Subscription(); 
    //other variables .. 

// changes to rows only happen after this lifecycle event so you need 
// to subscribe to the changes made in rows. 
// This subscription is to avoid memory leaks 
ngAfterViewInit() { 
    this.sub1 = this.rows.changes.subscribe(resp => { 
    if (this.rows.length > 1){ 
     this.rows.last.nativeElement.focus(); 
    } 
    }); 
    } 

    //memory leak avoidance 
    ngOnDestroy(){ 
    this.sub1.unsubscribe(); 
    } 


    //add a new input to the page 
    addInput() { 
    const formArray = this.form.get('inputs') as FormArray; 

    formArray.push(
     new FormGroup(
     {input: new FormControl(null, [Validators.required])} 
    )); 
    return true; 
    } 

// need for dynamic adds of elements to re 
//focus may not be needed by others 
trackByFn(index:any, item:any){ 
    return index; 
} 

模板逻辑看起来像这样:

<div formArrayName="inputs" class="col-md-6 col-12" 
    *ngFor="let inputCtrl of form.get('phones').controls; 
      let i=index; trackBy:trackByFn"> 
    <div [formGroupName]="i"> 
     <input #input type="text" class="phone" 
      (blur)="addRecord()" 
      formControlName="input" /> 
    </div> 
</div> 

在我的模板中,我添加了模糊记录,但您可以轻松设置按钮以动态添加下一个输入字段。重要的是,使用这段代码,新元素可以根据需要获得焦点。

让我知道你在想什么

相关问题