Data binding 变量更改时Angular2组件视图不更新

Data binding 变量更改时Angular2组件视图不更新,data-binding,angular,components,Data Binding,Angular,Components,我有一个简单的组件,它只呈现一个进度条 它初始化得很好,进度传递得很好,但是模板没有用新值更新 import {Component} from 'angular2/core'; @Component({ selector : 'progress-bar', template : ` <div class="progress-container"> <div>{{currentProgress}}</div> <d

我有一个简单的组件,它只呈现一个进度条

它初始化得很好,进度传递得很好,但是模板没有用新值更新

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;
  }
}
~

我觉得我错过了一些很好的补救措施。

你这样做的方式与框架背道而驰,会导致很多人哭诉和咬牙切齿

现在,您正在手动订阅一个可观察的-
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 ...
}
这里有两个关键区别需要注意:首先,
@Input()
告诉angular,
currentProgress
是一个输入属性。我们还将该属性的类型从
number
更改为
Observable
——这不是严格必要的,但它很有用,因为它允许第二个关键差异:

已添加到组件的
管道
,并在其到
currentProgress
的两个模板绑定中使用。这是很有用的,因为它告诉angular处理订阅可观察对象并在每次发出新值时更新UI的所有dirtywork

这就是它所需要的:现在,条的宽度和上面的文本都将自动更新,以反映从
httpFileService
发出的值,并且您不必编写一行代码
使之发生的命令式代码

如果你能更新你的问题来告诉我如何调用
onProgress
,我可能会让我的答案对你更有帮助-我怀疑这里使用了更深层次的反模式。添加了onProgress部分。它是通过我订阅的xhr onprogress检索的。我是对的:-)稍等片刻,我将更新我实现上述内容,但我面临的问题是进度条不会自动更新。但是,如果我单击该栏,效果会很好。该条将显示可观察到的当前值。有什么想法吗?@Hammer你描述的是一个变化检测问题是的。同意,但我将代码与此处共享的u进行比较,没有任何线索。。我把我的代码贴在这里,如果你能帮我看一下,我会很感激的?Tks。
@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 ...
}
@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
  }

}