簡體   English   中英

變量更改時Angular2組件視圖不會更新

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM