角度模型和渲染不同步

时间:2017-09-12 13:16:37

标签: angular

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

  1. 点击“添加”按钮
  2. ,向阵列添加3个新对象
  3. 使用某些数据填充输入字段
  4. 单击中间项目上的“删除”按钮将其删除
  5. 点击“添加”按钮
  6. 添加1个新对象

    是什么让UI与模型不同步?

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

    foreach (ITestCaseResult testCaseResult in resutlsToDisplay)
    {
        project.TestCases.Find(test.Id);
    
        var testRun = testCaseResult.GetTestRun();
        var testPlanEntry = project.TestPlans.Find(testRun.TestPlanId);
        var artifacts = testCaseResult.QueryAssociatedWorkItemArtifacts();
        if (testPlanEntry.Name != testPlan)
            continue;
    
        var testResult = new TestResult // CUSTOM CLASS
        {
            TestConfiguration = testCaseResult.TestConfigurationName,
            TestRun = testRun.Id,
            DateCreated = testRun.DateCreated,
            DateStarted = testRun.DateStarted,
            DateCompleted = testRun.DateCompleted,
            Result = testCaseResult.Outcome.ToString(),
            TestResultComment = testRun.Comment,
            RunBy = testCaseResult.RunBy == null ? "" : testCaseResult.RunBy.DisplayName,
            Build = testRun.BuildNumber ?? ""
        };
    
        foreach (var iteration in testCaseResult.Iterations)
        {
            var iterationResult = testResult.Clone();
            iterationResult.ResultAttachmentHtml = getAttachments(iteration.Attachments, testCase.TestCaseId.ToString(), string.Empty, iteration.IterationId.ToString()); // HERE I GET THE ATTACHMENTS OF TYPE 2
            iterationResult.Iteration = iteration.IterationId;
            iterationResult.IterationComment = iteration.Comment;
    
            foreach (var step in steps)
            {
                var stepCopy = step.Clone();
                iterationResult.Steps.Add(stepCopy);
                var actionResult = iteration.FindActionResult(stepCopy.TestStep);
                if (actionResult == null)
                    continue;
    
                stepCopy.Result.Comment = actionResult.ErrorMessage;
                stepCopy.Result.Result = actionResult.Outcome.ToString();
                stepCopy.Result.AttachmentHtml = getAttachments(actionResult.Attachments, testCase.TestCaseId.ToString(), step.Number, iteration.IterationId.ToString()); // HERE I DO NOT GET ATTACHMENTS OF TYPE 1 - WHY?
            }
            config.TestCaseResult.TestResults.Add(iterationResult);
        }
    } //end foreach testCaseResult in resutlsToDisplay
    

1 个答案:

答案 0 :(得分:3)

不要使用索引 i name 属性赋值。从数组中拼接项目时, 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;
}