javascript - Hur man sätter fokus på ett inputfält i ett formulärfält med ngIf


Jag står inför ett problem, jag vill i min kod sätta fokus på ett villkorat input baserat på data från en observable. I mitt exempel sätter jag bara en boolean till true i ngOnInit().

export class InputOverviewExample implements OnInit {
  bool: boolean;

  @ViewChild("input1", { static: true }) input1: MatInput;
  @ViewChild("input2", { static: true }) input2: MatInput;

  ngOnInit() {
    this.bool = true;
    this.input1.nativeElement.focus();
    this.input2.nativeElement.focus();
  }
}

Och jag märkte att fokus inte fungerar när ett mat-form-field är villkorligt.

<form class="example-form">
  <h3>Without *ngIf :</h3>
  <mat-form-field appearance="outline" class="example-full-width">
    <input matInput #input1 placeholder="Auto focus" value="Test_input1" />
  </mat-form-field>

  <h3>With *ngIf :</h3>
  <mat-form-field appearance="outline" class="example-full-width" *ngIf="bool">
    <input matInput #input2 placeholder="Auto focus" value="Test_input2" />
  </mat-form-field>
</form>

StackBlitz-länk

Någon skulle ha en lösning på detta problem

Tack

Svar #1

du behöver förstå ViewChild {static:true} och {static:false} och {read}

Så, definiera först din ViewChild som

@ViewChild("input1", { static: false,read:ElementRef }) input1: ElementRef;
@ViewChild("input2", { static: false,read:ElementRef }) input2: ElementRef;

Den static:false gör att Angular kontrollerar om det är under en *ngIf

read:ElementRef gör att din "input1" och "input2" ses som ElementRef, inte som MatInput

Den andra saken som du behöver är hur Angular fungerar. Angular utför alla åtgärder och uppdaterar applikationen, så om du skriver

this.bool = true;
this.input2.nativeElement.focus(); //<--this.input2 is undefined

this.input2 är odefinierad eftersom Angular inte har uppdaterat applikationen, så du behöver omsluta det med setTimeout - du kan tänka på setTimeout som att du säger till Angular "hej, glöm inte att efter att ha uppdaterat applikationen behöver du göra dessa andra instruktioner" - eller använd ChangeDetectorRef.

Så

  ngOnInit() {
    this.bool = true;
    setTimeout(()=>{
      this.input1.nativeElement.focus();
      this.input2.nativeElement.focus();
    })
  }

Svar #2

ngOnInit() {
    this.bool = true;
    if(...){
        this.input1.nativeElement.focus();
    }
    else{
        this.input2.nativeElement.focus();
    }
    
}