2016-01-16 20 views
2

後在Angular2 documentation on template syntax用於同時設置多個樣式的優選方法的示例代碼已經改變是這樣的:Angular2 ngClass文檔和表達式「setClasses()」它檢查異常

setStyles() { 
    let styles = { 
    // CSS property names 
    'font-style': this.canSave  ? 'italic' : 'normal', // italic 
    'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal 
    'font-size': this.isSpecial ? 'x-large': 'smaller', // larger 
    } 
    return styles; 
} 

稱爲像這樣:

<div [ngStyle]="setStyles()"> 
    This div is italic, normal weight, and x-large 
</div> 

然而,在英雄項目的旅遊嘗試這種代碼將導致以下錯誤:

Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode. 
EXCEPTION: Error during evaluation of "click" 
EXCEPTION: Expression 'setClasses() in [email protected]:10' has changed after it was checked. 
Previous value: '[object Object]'. Current value: '[object Object]' in [setClasses() in [email protected]:10] 

我知道這是Angular2強調單向數據流的動力的一部分,但考慮到這個例子是最佳實踐,發生了什麼?

我發現了一個對此問題的建議解決方案here,它沒有被接受的答案。討論結論:任何改變綁定需要在發生變化時觸發一輪更改檢測的事情。 在有一個鏈接到另一個答案,說,這筆記: 手動運行變化檢測:

Use ApplicationRef::tick() method. 
Use NgZone::run() method to wrap you code which should be executed inside angular zone. 

試圖然後使用方法app.tick();NgZone::run()雙雙突破整個應用程序,或者我只是用它錯誤。

我已創建this Plunker來演示此問題。選擇英雄時,名稱上的樣式應根據模型中可用的數據進行更改。例如,前五名英雄具有標準風格,但接下來的三名IQ博士,SkyDog和J-Dragon擁有不同的自我和權力。在開發模式下,您只能選擇一個,並且應用程序中斷消息: 在檢查後,表達式'setClasses()in AppComponent @ 11:10'已更改。

如果您取消註釋// enableProdMode();在boot.ts中,那麼應用程序工作正常。

那麼這是怎麼回事?我希望能夠以這種方式使用開發模式並使用ngClass。這樣做的最佳做法是什麼?

+0

當變更檢測正在評估'setStyles()'時,你可能不能調用'tick()'或'run()'。問題是'setStyles()'每次調用時都會返回一個新對象。嘗試使對象成爲一個組件屬性,而只是改變'setStyles()'中的對象屬性值。 –

回答

1

變化:

<h4 [ngClass]="setClasses()">

爲:

<h4 [ngClass]="classes">

,並調用setClasses方法在onSelect方法:

onSelect(hero: Hero) { 
    this.selectedHero = hero; 
    hero.power ? this.stylar1 = true: this.stylar1 = false; 
    hero.alterEgo ? this.stylar2 = true: this.stylar2 = false; 
    this.setClasses(); 
} 

http://plnkr.co/edit/95H4YNtdfn3y2KTdX8Xu?p=preview