2016-04-17 65 views
5

我有一個簡單的組件,它只是呈現一個進度條。當變量發生變化時,Angular2組件視圖不會更新

它初始化很好,進度傳遞給它很好,但模板沒有用新值更新。

import {Component} from 'angular2/core'; 

@Component({ 
    selector : 'progress-bar', 
    template : ` 
    <div class="progress-container"> 
     <div>{{currentProgress}}</div> 
     <div [style.width.%]="currentProgress" class="progress"></div> 
    </div> 
    `, 
    styles: [ 
    '.progress-container {width: 100%; height: 5px}', 
    '.progress {background-color: #8BC34A; height:5px}' 
    ] 
}) 

export class ProgressBar { 
    currentProgress: number; 

    constructor() { 
    this.currentProgress = 0; 
    } 

    onProgress(progress: number) { 
    console.log(progress) //consoles correct percentages 
    this.currentProgress = progress; 
    } 

    reset() { 
    console.log(this.currentProgress) //is 100 
    this.currentProgress = 0; 
    } 
} 
~ 

別處

ngOnInit() { 
    this.httpFileService.progress$.subscribe((progress: number) => this.onProgress(progress)); 
    } 

    onProgress(progress: number) { 
    this.progressBar.onProgress(progress*100); 
    } 

我覺得我失去了一些東西非常的補救。

+0

如果您將更新您的問題以向我展示'onProgress'是如何被調用的,我可能會讓我的答案對您更有幫助 - 我懷疑這裏有更深的反模式。 – drewmoore

+0

添加了onProgress部件。它通過我訂閱的xhr onprogress檢索。 – Dreamlines

+0

我是對的:-)只需一秒鐘,我就會更新 – drewmoore

回答

11

你正在以一種與框架相互作用的方式來解決這個問題,並且會導致大量的哭鬧和咬牙切齒。

現在,您正在手動訂閱observable - httpFileService.progress$ - 然後手動更新子組件ProgressBar上的屬性,繞過角度的更改檢測機制 - 這就是UI未更新的原因。你可能設置此屬性後,手動火災變化檢測和UI會更新如預期 - 但再次,你會對框架工作,所以讓我們看看如何使用它,而不是:

我假設「別處」是您的ProgressBar組件的父級 - 我們稱之爲ElsewhereComponent

@Component({ 
    selector: 'elsewhere', 
    directives: [ProgressBar], 
    template: ` 
    <div> 
     <progress-bar [currentProgress]="httpFileService.progress$"></progress-bar> 
    </div> 
    ` 
}) 
class ElsewhereComponent { 
    // you can remove the ngOnInit and onProgress functions you posted 
    // you also don't need a reference to the child ProgressBar component 
    // ... whatever else you have in this class ... 
} 

這裏要注意的最重要的事情是progress-bar部件上添加[currentProgress]:這是告訴角度,有一個名爲currentProgress應該被綁定到httpFileService.progress$該組件的輸入特性。

但是你現在已經對角度說謊了 - 因爲它站立起來,ProgressBar根本沒有任何輸入,當它試圖將這個不存在的屬性綁定到給定值時,angular會告訴你它。因此,我們需要添加輸入屬性,這樣做的最佳方式是與Input()裝飾:

@Component({ 
    selector : 'progress-bar', 
    pipes: [AsyncPipe] //import this from angular2/core 
    template : ` 
    <div class="progress-container"> 
     <div>{{currentProgress | async}}</div> 
     <div [style.width.%]="currentProgress | async" class="progress"></div> 
    </div> 
    ` 
}) 
export class ProgressBar { 
    @Input() currentProgress: Observable<number>; 
    ... 
    constructor(){ 
    // remove the line you have in here now 
    } 

} 

這裏有兩個關鍵需要注意的差異:首先,@Input()告訴角度說currentProgress是輸入屬性。我們還改變了從number該屬性的類型Observable<number> - 這不是絕對必要的,但因爲它允許第二個關鍵的區別是非常有用:

AsyncPipe已添加到組件的pipes,在上述兩種使用其模板綁定到currentProgress。這很有用,因爲它告訴angular處理所有訂閱Observable的髒東西,並在每次發佈新值時更新UI。

而這一切都需要:酒吧的兩個寬度和它上面現在會自動更新,以反映從httpFileService發出的價值觀,你沒得的 勢在必行一行代碼寫入文本實現它。

+0

我執行上述操作,但我面臨的問題是進度條不會自動更新。但是,如果我點擊欄,它運作良好。該欄會顯示來自觀察對象的當前值。任何想法? – Hammer

+0

@Hammer你描述的是變更檢測問題 – drewmoore

+0

是的。同意,但我比較代碼與你在這裏共享沒有任何線索..我粘貼我的代碼在這裏,感謝如果你可以幫助看看?韓國社交協會。 http://stackoverflow.com/questions/37046757/ui-is-not-updated-automatically-when-value-is-available-from-the-observable – Hammer

相關問題