programing

Angular2 입력이 변경되면 동적 입력 필드가 포커스를 잃음

closeapi 2023. 11. 7. 20:52
반응형

Angular2 입력이 변경되면 동적 입력 필드가 포커스를 잃음

역동적인 형태를 만들고 있습니다. A.Field값 목록을 가지고 있습니다.각 값은 문자열로 표시됩니다.

export class Field{
    name: string;
    values: string[] = [];
    fieldType: string;
    constructor(fieldType: string) {this.fieldType = fieldType;}
}

내 구성요소에 필드에 새로운 값을 추가하는 기능이 있습니다.

addValue(field){
    field.values.push("");
}

내 HTML에는 값과 버튼이 이렇게 표시됩니다.

<div id="dropdown-values" *ngFor="let value of field.values; let j=index">
    <input type="text" class="form-control" [(ngModel)]="field.values[j]" [name]="'value' + j + '.' + i"/><br/>
</div>
<div class="text-center">
    <a href="javascript:void(0);" (click)="addValue(field)"><i class="fa fa-plus-circle" aria-hidden="true"></i></a>
</div>

값 입력에 텍스트를 쓰는 순간 입력의 초점이 줄어듭니다.필드에 많은 값을 추가하고 입력된 값에 문자를 입력하면 입력된 값에 초점이 떨어지고 모든 입력에 문자가 기록됩니다.

이것은 배열이 원시 유형일 때 발생합니다. 당신의 경우 a.Stringarray. 이것은 사용하여 해결할 수 있습니다.TrackBy. 따라서 템플릿을 다음과 일치하도록 변경합니다.

<div *ngFor="let value of field.values; let i=index; trackBy:trackByFn">
    <input type="text" [(ngModel)]="field.values[i]"  /><br/>
</div>
<div>
    <button (click)="addValue(field)">Click</button>
</div>

그리고 ts 파일에 함수를 추가합니다.trackByFn, (unique)을 반환합니다.index다음의 가치:

trackByFn(index: any, item: any) {
   return index;
}

이것은 AngularJS에 대한 문제를 제외하고는 동일한 문제에 대한 링크입니다만, 문제는 당신의 것에 해당합니다.해당 페이지에서 가장 중요하게 발췌한 내용:

배열을 반복하는 중이며 배열의 항목을 변경하는 중입니다(항목은 문자열이며, 이 문자열은 JS의 프리미티브이므로 "값에 따라" 비교됩니다).새 항목이 감지되면 DOM에서 이전 요소가 제거되고 새 요소가 생성됩니다(분명히 포커스가 맞지 않음).

와 함께TrackByAngular는 고유 식별자에 따라 어떤 항목이 추가(또는 제거)되었는지 추적하고 변경된 항목만 생성 또는 소멸할 수 있으므로 입력 필드에 대한 초점을 잃지 않습니다 :)

링크에서 볼 수 있듯이 고유하고 사용하는 개체를 포함하도록 배열을 수정할 수도 있습니다.[(ngModel)]="value.id"예를 들어, 하지만 그것은 당신에게 필요한 것이 아닐 수도 있습니다.

도우미 기능을 사용하여 개체의 키와 값을 반복할 때 이러한 현상이 발생했습니다.

<div *ngFor="let thing of getThings()" [attr.thingname]="thing.key">
  ... {{ applyThing(thing.value) }}
</div>

구성 요소에서 키/값 쌍이 포함된 개체 배열을 반환하고 있었습니다.

export ThingComponent {
  ...

  //this.things = { a: { ... }, b: { ... }, c: { ... } }

  public getThings() {
    return Object.keys(this.things).map((key) => {
      return {key: key, value: this.things[key] }
    })
  }
}

@AJT_82에서 제시한 답변은 분명히 광고대로 정확하게 작동합니다.그러나 필자의 경우에는 도우미 기능이 문제가 된 것이고,getThings(), 매번 새로운 개체 목록을 반환하고 있었습니다.내용은 동일하지만 객체 자체는 함수에 호출할 때마다 재생되고(변경 탐지 중에 발생), 따라서 변경 탐지기에는 서로 다른 아이덴티티가 있으며 모델 변경 시마다 형태가 재생됩니다.

제 경우에는 결과를 캐슁하는 것이 간단한 솔루션이었습니다.getThings()그리고 그것을 반복자로 사용합니다.

<div *ngFor="let thing of cachedThings" [attr.thingname]="thing.key">
  ... {{ applyThing(thing.value) }}
</div>

...

export ThingComponent {
  public cachedThings = getThings()
  ...

  //this.things = { a: { ... }, b: { ... }, c: { ... } }

  private getThings() {
    return Object.keys(this.things).map((key) => {
      return {key: key, value: this.things[key] }
    })
  }
}

의 경우cachedThings변경 감지기가 다시 rendering하도록 수동으로 업데이트해야 합니다.

텍스트를 입력하면 각 ngOnChange 수신기가 실행되므로 ngFor 인덱스가 다시 렌더링되고 포커스가 손실됩니다.이 문제를 방지하기 위해 ngFor에 trackFn을 추가할 수 있습니다.이 주제에 대한 자세한 내용은 https://angular.io/api/core/TrackByFunction 을 참조하십시오.문제에 대한 코드 솔루션 아래:

당신의 html 코드는 .ts 파일에 선언된 trackByFn 함수에 해당할 ngFor a trackFn 함수를 정의합니다.

    <div *ngFor="let value of field.values; let i=index; trackBy:trackByFn">
    <input type="text" [(ngModel)]="field.values[i]"  /><br/>
</div>
<div>
    <button (click)="addValue(field)">Click</button>
</div>

그리고 ts 파일에서 위에 언급한 trackByFn 함수를 선언합니다.

trackByFn(i: number, items: any) {
return index //returning the index itself for avoiding ngFor to change focus after ngModelChange
}

언급URL : https://stackoverflow.com/questions/42322968/angular2-dynamic-input-field-lose-focus-when-input-changes

반응형