1

Я пытаюсь реализовать встроенное редактирование с использованием ngModel в Angular2. У меня есть массив, который нужно повторить с помощью ngFor, а также использовать ngModel. Когда я пытаюсь применить встроенное редактирование для этого массива, я могу редактировать только один символ для каждой из переменных массива.Angular2 Встроенное редактирование с использованием ngModel и ngFor

Рабочий стол here.

Вот код компонента, где я использую ngModel и ngFor вместе:

import {Component} from '@angular/core' 
import {InlineEditComponent} from './inline.component'; 
@Component({ 
    selector: 'inline-app', 
    providers: [], 
    template: ` 
    <div> 
     <h2>Inline Editing with Angular 2</h2> 
     <inline-edit [(ngModel)]="editableText" (onSave)="saveEditable($event)"></inline-edit> 
    </div> 
    <div> 
     <ul style="margin:5px;"> 
     <li ngFor #arr [ngForOf]="array" [ngForTrackBy]="customTrackBy"> 
     <inline-edit [(ngModel)]="arr" (onSave)="saveEditable($event)"></inline-edit> 
    </li> 
     // <li style="margin:5px;" *ngFor="let arr of array ; let i=index"> 
     // <inline-edit [(ngModel)]="array[i]" (onSave)="saveEditable($event)"></inline-edit> 
     // </li> 
     </ul> 
    </div> 
    `, 
    directives: [InlineEditComponent] 
}) 
export class InlineApp { 
customTrackBy(index: number, obj: any): any { 
    return index; 
    } 
    editableText = "Click to edit me!"; 
    // Save name to the server here. 
    saveEditable(value){ 
     console.log(value); 
    } 
    array=['bmw','benz','honda']; 
} 

Если кто-то может мне помочь, это было бы здорово.

ответ

2

Вы редактируете строки, которые являются неизменными и прямыми элементами массива. Это означает, что всякий раз, когда изменяется значение строки, будет создан новый строковый объект и заменит старую строку в массиве, что в свою очередь заставляет * ngFor повторно инициировать новый компонент для этой строки, чтобы заменить старый. Если вы положите console.log('on-constructor') в конструктор InlineEditComponent, вы увидите, что он вызывается каждый раз, когда вы добавляете символ.

Чтобы исправить возникшую проблему, не используйте строку напрямую. Заверните их в классе, как это:

export class Data { 
    name: string; 
} 

тогда ваша декларация массив будет:

array: Data[] = [ 
    {name:"bwm"}, 
    {name:"benz"}, 
    {name:"honda"} 
]; 

При этом изменения будут влиять только на имя поля, а объекты оболочки остаются неизменными; ngFor поэтому не будет запускаться для повторного запуска.

Модифицированный plnkr: https://plnkr.co/edit/WwGcLlisjGe1cmZOMHhD?p=preview

+0

я подумал, что было то, что происходит с @ проблемой Варуна в ... ваше решение довольно хорошо, но действие отмены больше не отменяется ... он по-прежнему сохраняет любые сделанные изменения –

+0

Да, я не делал проверки здравомыслия ко всем другим функциям, должен был предупредить об этом. Мои изменения были исключительно для решения проблемы, с которой он сталкивается :) –

+0

По сути, его решение предполагает создание модели - класса «Data». Это рекомендуемый способ реализации любого повторяющегося объекта данных. – BrianRT

0

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

<li *ngFor="let arr of array; let idx=index; ngForTrackBy:customTrackBy"> 
     <inline-edit [(ngModel)]="array[i]" (onSave)="saveEditable($event)"></inline-edit> 

Btw: ваш синтаксис ngFor может быть использован только на <template> тегов. Если вы используете его на других элементах, необходим синтаксис, использованный выше.

Смотрите также https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngFor

0

Это должно быть изменено в tamplate.

<ul> 
      <li style="margin:5px;" *ngFor="let arr of array ; let i=index; trackBy:customTrackBy"> 
      <inline-edit [(ngModel)]="array[i]" (onSave)="saveEditable($event)"></inline-edit> 
      </li> 
</ul> 

Эти функции должны быть добавлены в классе:

export class{ 

customTrackBy(index: number): any { 
    return index; 
    } 
} 

Окончательный рабочий код:
https://plnkr.co/edit/7SSpZDec2N2zjrSUM04X?p=preview