2017-09-12 70 views
7

我有一个Angular组件,它有一个按钮,它将一个新对象添加到作为模型的数组中。在我的组件模板中,我有一个* ngFor循环,遍历数组中的对象并显示对象属性的输入字段。我还在每个从数组中删除对象的对象旁边都有一个“删除”按钮。当我执行以下步骤时,UI将与模型不同步并清空除第一个项目之外的所有项目的字段。角度模型和渲染不同步

  1. 通过单击“添加”按钮
  2. 填充了一些数据输入字段添加到阵列3个的新对象
  3. 点击中间的项目删除按钮来删除它
  4. 新增1通过点击“添加”按钮的对象

什么使UI与模型不同步?

这是一个Plunker示例,演示了问题Example 我还在模板中添加了一行显示模型数组中的内容。

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
    <button (click)="things.push({})">+ Add new thing</button> 
     <br /> 
     <br /> 
     <form #contactForm="ngForm"> 
     <ng-container *ngFor="let thing of things;let i = index"> 
      <input [(ngModel)]="thing.name" name="name-{{i}}" id="name-{{i}}" placeholder="name"/> 
      <br /> 
      <input [(ngModel)]="thing.otherstuff" name="other-{{i}}" id="other-{{i}}" placeholder="other" /> 
      <button (click)="things.splice(i, 1)">Remove</button>   
      <br /> 
      <br /> 
     </ng-container> 
     </form> 
     {{things | json}} 
    </div> 
    `, 
}) 
export class App { 
    things: Awesome[] 
    constructor(){ 
    this.things = new Array(); 
    } 
} 

@NgModule({ 
    imports: [ 
    BrowserModule, 
    FormsModule 
    ], 
    declarations: [ App ], 
    bootstrap: [ App ] 
}) 
export class AppModule { 
} 

export class Awesome{ 
    name?: string; 
    otherstuff?: string; 
} 
+0

如果有3个对象,当您填写自己的输入字段与一些随机字符串,去掉中间的一个,然后单击添加按钮再次它清除了一切 –

+0

这是一个很好的问题 :)。要解决这个问题,只需将表单放入* ngFor – Cristophs0n

回答

2

不要使用索引给价值属性。 i当你从数组中拼接项目时不稳定,所以你必须为每个新增的东西(我提供了一个生成唯一ID的例证函数)生成一个唯一的ID。下面

代码工作:

//our root app component 
import { Component, NgModule, VERSION } from '@angular/core' 
import { BrowserModule } from '@angular/platform-browser' 
import { FormsModule } from "@angular/forms"; 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
    <button (click)="addEmptyItem()">+ Add new thing</button> 
     <br /> 
     <br /> 
     <form> 
     <ng-container *ngFor="let thing of things"> 
      <input [(ngModel)]="thing.name" name="name-{{thing.id}}" id="name-{{thing.id}}" placeholder="name"/> 
      <br /> 
      <input [(ngModel)]="thing.otherstuff" name="other-{{thing.id}}" id="other-{{thing.id}}" placeholder="other" /> 
      <button (click)="removeItem(thing)">Remove</button>   
      <br /> 
      <br /> 
     </ng-container> 
     </form> 
     {{things | json}} 
    </div> 
    `, 
}) 
export class App { 

    things: Awesome[] 
    constructor() { 
     this.things = new Array(); 
    } 
    removeItem(thing): void { 
     this.things = this.things.filter(th => th.name !== thing.name); 
    } 
    addEmptyItem(): void { 
     let newItem = new Awesome(); 
     newItem.id = this.guid(); 
     this.things.push(newItem); 
    } 

    private guid() { 
     let uniqueId = Math.random().toString(36).substring(2) 
      + (new Date()).getTime().toString(36); 
     return uniqueId; 
    } 
} 

@NgModule({ 
    imports: [ 
     BrowserModule, 
     FormsModule 
    ], 
    declarations: [App], 
    bootstrap: [App] 
}) 

export class AppModule { 
} 

export class Awesome { 
    id?: string; 
    name?: string; 
    otherstuff?: string; 
} 
+0

即可。谢谢!起初我以为这可能是一个问题,从这个[问题]的HTML元素的命名(https://stackoverflow.com/questions/38639560/dynamic-angular2-form-with-ngmodel-of-ngfor-elements )但现在我意识到我必须为每个项目提供一个唯一的标识符。再次感谢。 –