ViewChild and focus()

2019-05-24 02:17发布

I have a component which contains a textarea which is hidden by default :

<div class="action ui-g-2" (click)="toggleEditable()">edit</div>
<textarea [hidden]="!whyModel.inEdition" #myname id="textBox_{{whyModel.id}}" pInputTextarea focus="true" [(ngModel)]="whyModel.description"></textarea>

When I click on the "edit" div I want to show the textarea and put focus on it :

@ViewChild('myname') input: ElementRef;
...
private toggleEditable(): void {
  this.whyModel.toggleEditable();
  this.input.nativeElement.focus();
}

The "show" part is working but not the focus part. What do I miss?

3条回答
smile是对你的礼貌
2楼-- · 2019-05-24 02:34

You can use @ViewChild and focus() to focus on a particular element. It can be used like this:

In HTML file (abc.component.html)

<form #data="ngForm">
<input class="text-field" type="text" name="name" >
<input class="text-field" type="text" name="surname">
<input class="text-field" type="text" name="company">
</form>


<button type="submit" value="Submit" (click)="submitData(data.value)">Submit</button>


<input class="text-field" type="text" name="City" #setFocusField>
<input class="text-field" type="text" name="State">

In TypeScript file (abc.component.ts)

@ViewChild('setFocusField') setFocusField: any;

submitData(data:any){
  this.setFocusField.focus();
}

When you click on the submit button, the focus will be set to the field "City".

Another way to achieve this:

In above code, instead of any on ViewChild field, we can use ElementRef.

In that case typescript file changes will be as follow:

(abc.component.ts)

@ViewChild('setFocusField') setFocusField: ElementRef;

submitData(data:any){
  this.setFocusField.nativeElement.focus();
}
查看更多
\"骚年 ilove
3楼-- · 2019-05-24 02:48

You can also 'force' the focus with AfterViewCheck. I simplified your code for the demo purposes:

Typescript:

  editable;

  @ViewChild('myname') input: ElementRef;
  private toggleEditable(): void {
      this.editable = !this.editable;
   }

   ngAfterViewChecked(){
     if(this.editable){
          this.input.nativeElement.focus();
     }
   }

HTML

<div class="action ui-g-2" (click)="toggleEditable()">edit</div>
<br>
<textarea [hidden]="!editable" #myname id="textBox_{{id}}" pInputTextarea
   focus="true" [(ngModel)]="description"></textarea>

Stackblitz example

查看更多
叼着烟拽天下
4楼-- · 2019-05-24 02:49

Bindings are only updated when change detection runs, which is usually after an event handler completed. This is to late for your use case, because the event handler itself depends already on the effect of change detection.

You can enforce change detection immediately (synchronically) by calling detectChanges()

constructor(private cdRef:ChangeDetectorRef) {}

@ViewChild('myname') input: ElementRef;
...
private toggleEditable(): void {
  this.whyModel.toggleEditable();
  this.cdRef.detectChanges();
  this.input.nativeElement.focus();
}
查看更多
登录 后发表回答