[英]Angular2 component view not updating when variable changes
我有一個簡單的組件,只是呈現進度條。
它初始化很好,進度很好,但模板沒有使用新值更新。
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);
}
我覺得我錯過了一些非常有用的東西。
你正在以一種與框架相對立的方式來解決這個問題,並且會導致更多的嚎叫和咬牙切齒。
現在,您手動訂閱一個observable - httpFileService.progress$
- 然后手動更新子ProgressBar
組件上的屬性,繞過angular的更改檢測機制 - 這就是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]
:這就是告訴angular,在該組件上有一個名為currentProgress
的輸入屬性應綁定到httpFileService.progress$
。
但你現在已經撒謊了 - 就像它所說的那樣, ProgressBar
根本就沒有輸入,當它試圖將這個不存在的屬性綁定到給定值時,angular會告訴你它。 所以我們需要添加input屬性,並且首選的方法是使用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()
告訴angular currentProgress
是一個輸入屬性。 我們還將該屬性的類型從number
更改為Observable<number>
- 這不是絕對必要的,但它很有用,因為它允許第二個關鍵區別:
AsyncPipe
已添加到組件的pipes
,並在其與currentProgress
兩個模板綁定中使用。 這很有用,因為它告訴angular處理訂閱Observable的所有臟工作,並在每次發出新值時更新UI。
這就是它所需要的:條形圖的寬度和它上面的文本現在都會自動更新以反映從httpFileService
發出的值,並且您不必編寫一行命令性代碼來實現它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.