初始计数器值未显示在ChangeDetectionPush策略上

时间:2019-02-24 06:29:47

标签: javascript angular

我正在写一个简单的counter。它在start,stop, toggle中具有parent (app功能,并使用child (counter) componentChangeDetectionStrategy.OnPush中显示更改的值。

我面临的问题是在加载时子组件中无法显示initial counter value

下面是屏幕截图和代码。

enter image description here

app.component.ts

import { Component } from '@angular/core';
import {BehaviorSubject} from 'rxjs';

@Component({
selector: 'app-root',
template: `<h1>Change Detection</h1>

<button (click)="start()">Start</button>
<button (click)="stop()">Stop</button>
<button (click)="toggleCD()">Toggle CD</button>
<hr>
<counter [data]="data$" [notifier]="notifier$"></counter>`,
})
export class AppComponent {

_counter = 0;
_interval;
_cdEnabled = false;
data$ = new BehaviorSubject({counter: 0});
notifier$ = new BehaviorSubject(false);

start() {
 if (!this._interval) {
    this._interval = setInterval((() => {
        this.data$.next({counter: ++this._counter});
    }), 10);
 }
}

stop() {
 clearInterval(this._interval);
 this._interval = null;
}
toggleCD(){
  this._cdEnabled = !this._cdEnabled;
  this.notifier$.next(this._cdEnabled);
 }
}

counter.component.ts

import {Component, Input, ChangeDetectionStrategy, OnInit, ChangeDetectorRef} from '@angular/core';
import {Observable} from 'rxjs/index';

 @Component({
  selector: 'counter',
  template: `Items: {{_data.counter}}`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CounterComponent implements OnInit {

@Input() data: Observable<any>;
@Input() notifier: Observable<boolean>;
_data: any;

constructor(private cd: ChangeDetectorRef) {}

ngOnInit() {
  this.data.subscribe((value) => {
  /**
  Below this._data.counter is showing 0 in console.log but
  not in template
  **/
  this._data = value;
  this.cd.markForCheck();
});

this.cd.detach();
this.notifier.subscribe((value) => {
  if (value) {
       this.cd.reattach();
    } else {
      this.cd.detach();
    }
  });
 }
}

我正在使用Angular 6.1.0

1 个答案:

答案 0 :(得分:1)

您的AppComponent data$是一个BehaviorSubject,您已为其指定了初始值。您的CounterComponent data需要您订阅的Observable。默认的BehaviorSubject在更改之前不会触发。要获取值,您必须在加载时查询它:

@Input() data: BehaviorSubject<any>;

ngOnInit() {
  this._data = this.data.value; // get the initial value from the subject
  this.data.subscribe((value) => {
    this._data = value;
    this.cd.markForCheck();
  }
);

应该可以解决问题。