在我的Angular 2应用程序中,我想要输入列表。在其中之一中按Enter键将添加一个新输入,并立即专注于此。这个问题已经在此站点和Eric Martinez provided a neat answer to it that accomplishes that with a custom directive上提出过。

他的解决方案基于整数的虚拟列表。我在尝试使其适应更现实的情况时遇到困难。我 fork 了埃里克(Eric)的小事,所以可以run the code here,但是最重要的文件是这个文件:

//our root app component
import {Component, Directive, Renderer, ElementRef} from 'angular2/core'

class Person { name: string }

@Directive({
  selector : 'input'
})
class MyInput {
  constructor(public renderer: Renderer, public elementRef: ElementRef) {}

  // It won't work at construction time
  ngOnInit() {
    this.renderer.invokeElementMethod(
      this.elementRef.nativeElement, 'focus', []);
  }
}

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div *ngFor="#input of inputs">
      <input
        (keydown.enter)="add()"
        [(ngModel)]="input.name"
        type="text"/>
    </div>
  `,
  directives: [MyInput]
})
export class App {
  inputs: Person[] = [{name: 'Alice'}];

  add() {
    var newPerson = new Person();
    newPerson.name = 'Bob';

    this.inputs.push(newPerson);
  }
}

我的inputs数组现在是Person对象的列表。输入双向绑定(bind)到namePerson属性。现在,<input>包装在<div>中,因为我希望以后我将编写更多标记来显示每个Person

进行了这些更改之后,该示例仅在按Enter的第一次尝试时才起作用-出现带有文本Bob的新输入。但是,当我第二次尝试按Enter时,出现错误:
angular2.dev.js:23730 Error: Expression 'ngClassUntouched in App@2:6' has changed after it was checked. Previous value: 'true'. Current value: 'false'
    at ExpressionChangedAfterItHasBeenCheckedException.BaseException [as constructor] (angular2.dev.js:7587)
    at new ExpressionChangedAfterItHasBeenCheckedException (angular2.dev.js:4992)
    at ChangeDetector_App_1.AbstractChangeDetector.throwOnChangeError (angular2.dev.js:9989)
    at ChangeDetector_App_1.detectChangesInRecordsInternal (viewFactory_App:143)
    at ChangeDetector_App_1.AbstractChangeDetector.detectChangesInRecords (angular2.dev.js:9874)
    at ChangeDetector_App_1.AbstractChangeDetector.runDetectChanges (angular2.dev.js:9857)
    at ChangeDetector_App_0.AbstractChangeDetector._detectChangesContentChildren (angular2.dev.js:9930)
    at ChangeDetector_App_0.AbstractChangeDetector.runDetectChanges (angular2.dev.js:9858)
    at ChangeDetector_HostApp_0.AbstractChangeDetector._detectChangesInViewChildren (angular2.dev.js:9936)
    at ChangeDetector_HostApp_0.AbstractChangeDetector.runDetectChanges (angular2.dev.js:9861)

我该如何解决?

我正在Chrome中运行示例。我发现使用基于Angular2 beta 12版本的埃里克·马丁内斯(Eric Martinez)的插件来解决问题最容易,但是在我遇到相同错误的现实应用中,当前使用的是Angular 2.0.0。

最佳答案

Angular2不喜欢在更改检测回调过程中更改模型时(例如ngOnInit())。调用ChangeDetectorRef.detectChanges()应该可以解决此问题:

class MyInput {
  constructor(public renderer: Renderer, public elementRef: ElementRef
      ,private cdRef:ChangeDetectorRef) {}

  // It won't work at construction time
  ngOnInit() {
    this.renderer.invokeElementMethod(
      this.elementRef.nativeElement, 'focus', []);
    this.cdRef.detectChanges();
  }
}

关于Angular 2 : focusing input causes 'expression has changed after it was changed' error,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40562845/

10-10 05:45