2016-11-12 21 views
3

在我的Angular 2應用程序,我想有一個輸入列表。按下其中一個裏面的Enter將添加一個新的輸入,並立即關注它。這是本網站上已詢問的問題,Eric Martinez provided a neat answer to it that accomplishes that with a custom directiveAngular 2:焦點輸入原因'表達已改變後,它被改變'錯誤

他的解決方案基於一個虛擬的整數列表。我在嘗試將其適應更現實的場景方面遇到困難。我已付出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對象的列表。輸入雙向綁定到Personname屬性。 <input>現在被包裝在一個<div>內,因爲我預計稍後我會寫更多標記來顯示每個Person

做出這些更改後,該示例僅在第一次嘗試按Enter時起作用 - 帶文本的新輸入Bob按預期顯示。但是,當我再嘗試按Enter鍵第二次,我得到一個錯誤:

angular2.dev.js:23730 Error: Expression 'ngClassUntouched in [email protected]: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。

回答

3

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

在Plunker這樣做會導致鉻因內存不足錯誤的崩潰,因爲某種原因。在我的真實應用程序中,即使底層數組仍然附加到後面,也會阻止出現任何新的「」。我也不太清楚我改變模型的方式。 – kamilk

+1

不管怎麼樣,你都不應該試着把注意力集中在'ngOnInit()上,因爲這裏的元素還不存在。使用'ngAfterViewInit()'或'ngAfterViewChecked()'。 –

+0

我嘗試了兩個事件,我嘗試將它們與'.detectChanges()'結合使用,仍然是同樣的問題... https://plnkr.co/edit/Hh3H36fceFSm0Q20PVV3?p=preview – kamilk