отображение и скрытие ввода в ngfor для редактирования значения с угловым материалом

Я пытаюсь сделать простой список предметов:

введите здесь описание изображения

для этого я использую список матов, содержащий диапазон для режима чтения и ввод в режиме редактирования. Я использую скрытый атрибут диапазона как логическое значение для переключения между двумя режимами. Я хотел бы переключиться в режим чтения, если фокус ввода потерян, поэтому я использовал (размытие):

<mat-list>
  <mat-list-item *ngFor="let item of list">
    <span #itemDisplay >{{item}}</span>
    <mat-form-field *ngIf="itemDisplay.hidden">
      <input matInput [(ngModel)]="updateItem" [formControl]="updateItemFormControl" [hidden]="!itemDisplay.hidden" (blur)="itemDisplay.hidden=false;" minlength="3" maxlength="10" autofocus #edit>
    <mat-error *ngIf="updateItemFormControl.hasError('required')">
      add label to your item
    </mat-error>
    <mat-error *ngIf="updateItemFormControl.hasError('minlength')">
      min 3 caracters
    </mat-error>
    <mat-hint align="end">{{edit.value.length}} / 128</mat-hint>
    </mat-form-field>

  <button mat-icon-button (mousedown)="changeItem(list.indexOf(item)); itemDisplay.hidden = false;" *ngIf="itemDisplay.hidden"><mat-icon>check_circle</mat-icon></button>
  <button mat-icon-button (click)="updateItem='';itemDisplay.hidden = true;" *ngIf="!itemDisplay.hidden"><mat-icon>edit</mat-icon></button>
  <button mat-icon-button (click)="list.splice(list.indexOf(item), 1)" *ngIf="!itemDisplay.hidden"><mat-icon>delete</mat-icon></button>
  </mat-list-item>

  <mat-list>
    <mat-form-field>
    <input matInput [(ngModel)]="newItem" [formControl]="newItemFormControl" placeholder="Add item" minlength="3" maxlength="10" #add>
    <mat-error *ngIf="newItemFormControl.hasError('required')">
      add label to your item
    </mat-error>
    <mat-error *ngIf="newItemFormControl.hasError('minlength')">
      min 3 caracters
    </mat-error>
    <mat-hint align="end">{{add.value.length}} / 128</mat-hint>
    </mat-form-field>
    <button mat-icon-button (click)="list.push(newItem);newItem=''" [hidden]="false" [disabled]="!newItemFormControl.valid">
      <mat-icon>add_circle</mat-icon></button>
  </mat-list>
</mat-list>

он отлично работает в первый раз, когда я нажимаю кнопку редактирования, но во второй раз он не фокусируется. И после второго раза у меня может быть два входа одновременно. Обычно предполагается, что размытие переключит itemDisplay.hidden на false и скроет диапазон.

Я хотел делать логические вещи без лишнего кода. ты понимаешь проблему?

это мой машинописный текст:

@Component({
  selector: 'list-overview-example',
  templateUrl: 'list-overview-example.html',
  styleUrls: ['list-overview-example.css'],
})
export class ListOverviewExample {

  list:Array<string> = ['item 1','item 2','item 3'] ;
  newItemFormControl: FormControl = new FormControl(this.newItem,[
    Validators.required,
    Validators.minLength(4),
    Validators.maxLength(128)
  ]) ;
  updateItemFormControl: FormControl = new FormControl(this.updateItem,[
    Validators.required,
    Validators.minLength(4),
    Validators.maxLength(128)
  ]) ;

  newItem: string ;
  updateItem: string;

  changeItem(i){
    this.list[i] = this.updateItem ;
    this.updateItem = '';
  }

}

вот ссылка на stackblitz: https://stackblitz.com/edit/angular-xoxuzn


person Lucas Weibel    schedule 12.11.2018    source источник
comment
Не могли бы вы предоставить для него stackblitz?   -  person SeleM    schedule 12.11.2018


Ответы (1)


В вашем случае Angular повторяет итерацию по списку, если в массиве обнаружено какое-либо изменение. Вы должны использовать trackBy, чтобы сообщить angular, что именно изменилось, чтобы он обновил элемент строки, который действительно изменился. Из-за такой реконструкции всего вида вы теряете фокус.

Внесите следующие изменения

html

<mat-list-item *ngFor="let item of list; trackBy:trackByIndex">

ts

 trackByIndex(index: number, obj: any): any {
    return index;
  }
person Sunil Singh    schedule 12.11.2018
comment
Спасибо за ответ, я изменил это в stackblitz, но вы можете видеть, что ввод получает фокус при первом нажатии кнопки редактирования, но если вы щелкнете за пределами ввода и попытаетесь отредактировать снова, это не так. сфокусируйтесь на второй раз. - person Lucas Weibel; 13.11.2018