加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

数据绑定 – 当变量发生更改时,Angular2组件视图不会更新

发布时间:2020-12-17 06:53:20 所属栏目:安全 来源:网络整理
导读:我有一个简单的组件,只是呈现进度条. 它初始化很好,进度很好,但模板没有使用新值更新. import {Component} from 'angular2/core';@Component({ selector : 'progress-bar',template : ` div class="progress-container" div{{currentProgress}}/div div [sty
我有一个简单的组件,只是呈现进度条.

它初始化很好,进度很好,但模板没有使用新值更新.

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()装饰器:

@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是一个输入属性.我们还将该属性的类型从数字更改为Observable< number> – 这不是绝对必要的,但它很有用,因为它允许第二个关键区别:

AsyncPipe已添加到组件的管道中,并在其与currentProgress的两个模板绑定中使用.这很有用,因为它告诉angular处理订阅Observable的所有脏工作,并在每次发出新值时更新UI.

这就是所需要的:条形图的宽度和它上面的文本现在都会自动更新,以反映从httpFileService发出的值,而且您不必编写一行实现它的命令性代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读