角度模型和渲染不同步 [英] Angular model and rendering out of sync

查看:64
本文介绍了角度模型和渲染不同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Angular组件,该组件具有一个按钮,该按钮将新对象添加到用作模型的数组中.在我的组件模板中,我有一个* ngFor循环,该循环遍历数组中的对象并显示对象属性的输入字段.我还在每个对象旁边有一个删除"按钮,用于从数组中删除对象.当我执行以下步骤时,UI与模型不同步,并清空除第一个项目外的所有项目的字段.

I have an Angular component that has a button which adds a new object to an array that serves as a model. In my component template, I have an *ngFor loop which iterates through the objects in the array and displays input fields for the properties of the object. I also have a "remove" button next to each object that removes the object from the array. When I do the following steps the UI goes out of sync with the model and empties the fields of all items except the first one.

  1. 通过单击添加"按钮将3个新对象添加到阵列中
  2. 用一些数据填充输入字段
  3. 单击中间项目上的删除"按钮将其删除
  4. 通过单击添加"按钮添加1个新对象

什么使UI与模型不同步?

What is making the UI go out of sync with the model?

这是一个说明问题的Plunker示例,示例 我还在模板中添加了一行,以显示模型数组中的内容.

Here is a Plunker example that demonstrates the issue Example I also added a line in the template that shows what is in the model array.

@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;
}

推荐答案

不要使用索引 i name 属性提供值. i 在从数组中拼接项目时不稳定,因此您必须为每个新添加的事物生成唯一的ID(我提供了一个生成唯一ID的示例函数).

Don't use index i to give value for name attribute. i is not stable when splicing items from your array so you have to generate an unique id for each new added thing (I provided an exemple function that generate unique 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;
}

这篇关于角度模型和渲染不同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆