Angular 2:聚焦输入导致'表达式在更改后发生了变化'错误

时间:2016-11-12 12:29:13

标签: angular typescript angular2-directives

在我的Angular 2应用程序中,我想要一个输入列表。在其中一个内部按Enter将添加一个新输入并立即关注它。这是一个已经在本网站和Eric Martinez provided a neat answer to it that accomplishes that with a custom directive上提出的问题。

他的解决方案基于一个虚拟的整数列表。我在努力使其适应更现实的情况时遇到了困难。我已经分叉了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个对象的列表。输入双向绑定到name的{​​{1}}属性。 Person现在包含在<input>内,因为我希望稍后我会写更多标记来显示每个<div>

进行这些更改后,该示例仅在第一次按Enter键时起作用 - 带有文本 Bob 的新输入按预期显示。但是,当我第二次尝试按Enter键时,出现错误:

Person

我该如何解决?

我在Chrome中运行该示例。我发现使用基于Beta 12版Angular2的Eric Martinez的插件来解决这个问题是最简单的,但是我得到同样错误的真实世界应用程序目前正在使用Angular 2.0.0。

1 个答案:

答案 0 :(得分:4)

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();
  }
}