Angular - Как получить входное значение в цикле ngFor с односторонней привязкой - PullRequest
0 голосов
/ 30 мая 2018

Можете ли вы дать мне способ получения входного значения в цикле ngFor с односторонним связыванием?

<div *ngFor="let d of dataList">
  <input #inputValue type="text" [ngValue]="d.value">
  <button *ngIf="!d.open" (click)="d.open = true">change</button>
  <button *ngIf="d.open" (click)="save(d.id, NEWVALUE); d.open = false;">save</button>
  <button *ngIf="d.open" (click)="d.open = false">cancel</button>
</div>`

Как установить NEWVALUE?с двусторонней привязкой легко.но после нажатия кнопки отмены значение уже изменилось, поскольку я не хочу.Так что я бы избежал этого.

Одно из найденных мной решений - это использование (ngModelChange).

<div *ngFor="let d of dataList">
  <input #inputValue type="text" [ngValue]="d.value" (ngModelChange)="dataChanged($event)">
  <button *ngIf="!d.open" (click)="d.open = true">change</button>
  <button *ngIf="d.open" (click)="save(d.id); d.open = false;">save</button>
  <button *ngIf="d.open" (click)="d.open = false">cancel</button>
</div>


private newVal;
dataChanged(val) {
  this.newVal = val;
}
save(id) {
  saveDb(id, this.newVal);
}

Это не совсем понятный и оптимизированный код, как мне кажется.

Как я знаю, связывание шаблонов с # также не работает с ngFor.как

<div *ngFor="let d of dataList">
  <input #inputValue_{{d.id}} type="text" [ngValue]="d.value">
  <button *ngIf="d.open" (click)="save(inputValue_{{d.id}}.value); d.open = false;">save</button>
</div>

У вас есть хорошее решение для меня?

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Вы можете дублировать массив и использовать данные из исходного массива, чтобы установить предыдущее значение, как если бы оно было в памяти.

См. Мой пример кода: https://stackblitz.com/edit/angular-a4eucy

0 голосов
/ 30 мая 2018

Вы можете создать новый компонент, который будет представлять элемент из списка.

app-item-list.ts

import { Component, Input, Ouput, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-item-list'
  templateUrl: './app-item-list.html'
})

export class ItemListComponent {

  newValue: string;
  @Input() data: YourDataClassType;
  @Output() onUpdate: EventEmitter<{id: number, newValue: string}>;

  contructor() {

    this.onUpdate = new EventEmitter<{id: number, newValue: string}>;
    this.newValue = data.value;
  }

  save() {

    this.onUpdate.emit({id: this.data.id, newValue: this.newValue});
  }
}

app-item-list.html

<div>
  <input type="text" [(ngValue)]="newValue">
  <button *ngIf="!data.open" (click)="data.open = true">change</button>
  <button *ngIf="data.open" (click)="save(); d.open = false;">save</button>
  <button *ngIf="data.open" (click)="data.open = false">cancel</button>
</div>

parent-component.html

<app-item-list *ngFor="let d of datalist" [data]="d" (onUpdate)="save($event)" />

parent-component.ts

save($event) {
  console.log($event.id, $event.newValue);
}

Не забудьте включить 'app-item-list' в ваше объявление модуля.

Этот код может нуждаться в некотором рефакторинге.Я сделал это без тестирования и какое-то время не использую angular.

0 голосов
/ 30 мая 2018

Невозможно, чтобы вы предоставили переменную шаблона напрямую, но я сделал для вас альтернативу

HTML

<div *ngFor="let item of array">
  <input id="id_{{item.id}}" />
  <button type="button" (click)="printValue('id_'+item.id)"> buton {{item.id}}   </button>
</div>

Компонент

export class AppComponent  {
  array = [{id: 1}, {id: 2},{id: 3}]

  printValue(value: any){
    console.log(value);
    var containputiner = document.querySelector("#"+value);
    console.log(containputiner.value);
  }
}

Демонстрация Stackblitz

...