[英]Angular4 ngOnInit rxjs/Subject not working
I have Directive
which has Subscription
for resize chart 我有
Directive
,其中包含用于尺寸调整图的Subscription
import {Directive, ElementRef, HostListener, Input, OnDestroy, OnInit} from '@angular/core';
import {Subscription} from 'rxjs/Subscription';
import echarts from 'echarts';
import 'echarts/theme/macarons';
import {ChartService} from '../service/chart/chart.service';
@Directive({selector: '[appECharts]'})
export class EChartsDirective implements OnInit, OnDestroy {
element: ElementRef;
subscription: Subscription;
@Input() eChartsOptions: any;
@Input() theme = 'macarons';
private chart;
constructor(element: ElementRef, private chartsService: ChartService) {
this.element = element;
}
ngOnInit() {
this.subscription = this.chartsService.chartChange.subscribe((str) => {
this.resizeChart(str);
});
this.chart = echarts.init(this.element.nativeElement, this.theme);
if (this.eChartsOptions) {
this.chart.setOption(this.eChartsOptions);
}
}
ngOnDestroy() {
if (this.chart) {
this.chart = null;
}
this.subscription.unsubscribe();
}
resizeChart(str: string) {
console.log('resize from=' + str);
setTimeout(() => {
if (this.chart) {
console.log('resize');
this.chart.resize();
}
}, 500);
}
@HostListener('window:resize')
onResize() {
this.resizeChart('window');
}
}
ChartService: 的ChartService:
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class ChartService {
chartChange = new Subject<string>();
orderChartChanged = new Subject<any[]>();
private orderCharts: any[];
setChartData(orderCharts) {
this.orderCharts = orderCharts;
this.orderChartChanged.next(this.orderCharts);
}
updateCharts(srt: string) {
console.log('from=' + srt);
this.chartChange.next(srt);
}
}
And Component where I calling updateCharts
method 还有我调用
updateCharts
方法的组件
import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {ChartHttpService} from '../../shared/service/chart/chart-http.service';
import {MdSnackBar} from '@angular/material';
import {Subscription} from 'rxjs/Subscription';
import {ChartService} from '../../shared/service/chart/chart.service';
import echarts from 'echarts';
import 'echarts/theme/macarons';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnDestroy, OnInit {
chartSubscription: Subscription;
@ViewChild('chart1') element: ElementRef;
chart2;
constructor(private chartService: ChartService,
private chartHttpService: ChartHttpService,
public snackBar: MdSnackBar) {
}
ngOnInit() {
const chart = echarts.init(this.element.nativeElement, 'macarons');
this.chartSubscription = this.chartService.orderChartChanged
.subscribe(
(response: any) => {
const option = response.orderAmount;
chart.setOption(option);
setTimeout(() => {
chart.resize();
}, 500);
this.chart2 = option;
this.chartService.updateCharts('home');
}
);
this.chartHttpService.orderCharts(this.snackBar);
}
ngOnDestroy() {
this.chartSubscription.unsubscribe();
this.chart2 = null;
}
onResize() {
this.chartService.updateCharts('btn');
}
}
ChartHttpService: ChartHttpService:
import {Injectable} from '@angular/core';
import {MdSnackBar} from '@angular/material';
import {HttpClient} from '@angular/common/http';
import {TranslateService} from '@ngx-translate/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';
import {SnackBarUtils} from '../snack-bar-utils';
import {environment} from '../../../../environments/environment';
import {ChartService} from './chart.service';
@Injectable()
export class ChartHttpService {
private static orderCharts = 'json/chart/ordersChart';
constructor(private http: HttpClient,
private chartService: ChartService,
private translate: TranslateService) {
}
orderCharts(snackBar: MdSnackBar) {
const url = environment.apiUrl + ChartHttpService.orderCharts;
this.http.get(url)
.catch(error => {
return Observable.throw(error);
})
.subscribe(
response => this.chartService.setChartData(response),
error => SnackBarUtils.showLocalizedSnackBar(this.translate, snackBar, 'msg.error')
);
}
}
And html component: 和html组件:
<div class="row">
<div class="col-lg-6 col-md-6 col-xs-12 col-sm-6">
<md-card>
<div class="box-header">Base Line</div>
<div #chart1 style="height: 300px;"></div>
</md-card>
</div>
<div class="col-lg-6 col-md-6 col-xs-12 col-sm-6">
<md-card>
<div class="box-header">Stacked Line</div>
<ng-container *ngIf="chart2">
<div appECharts [eChartsOptions]="chart2" style="height: 300px;"></div>
</ng-container>
</md-card>
</div>
<button (click)="onResize()">Resize</button>
</div>
So the problem is when I press refresh
in browser or f5
, updateCharts
method invokes in HomeComponent
but chartChange
Subject didn't work I guess, because in EChartsDirective
subscription didn't invoke method resizeChart
, and this problem is ONLY after refresh
or f5
. 所以,当我按下问题是
refresh
在浏览器或f5
, updateCharts
方法调用中HomeComponent
但chartChange
主题没有工作我猜的,因为在EChartsDirective
认购不调用方法resizeChart
,之后只有这个问题是refresh
或f5
。 If i click on Resize btn, everything works fine. 如果我单击“调整btn大小”,一切正常。
So i don't know why, but subscription
in EChartsDirective
didn't invoke resizeChart
after refresh
or f5
. 所以我不知道为什么,但是在
refresh
或f5
之后, EChartsDirective
subscription
未调用resizeChart
。
Any ideas why its happens? 任何想法为什么会发生?
UPDATE: And problem only with chart2
, I add chart1, which i init
manually(without Directive) in HomeComponent -> ngOnInit
, and when i'm calling 更新:而且只有
chart2
问题,我添加了chart2
,我在HomeComponent -> ngOnInit
手动init
(没有指令),并且在调用时
setTimeout(() => {
chart.resize();
}, 500);
It works, but of course, problem only with Subscription, but still) 它有效,但当然仅订阅有问题,但仍然)
UPDATE2: Change to: UPDATE2:更改为:
ngOnInit() {
this.chart = echarts.init(this.element.nativeElement, this.theme);
if (this.eChartsOptions) {
this.chart.setOption(this.eChartsOptions);
}
this.subscription = this.chartsService.chartChange.subscribe((str) => {
this.resizeChart(str);
});
}
nothing changed 没有改变
Log after browser refresh
or F5
browser refresh
或F5
后登录
from=home-123
Log after click to Resize btn 单击以调整btn大小后登录
from=xxx chart.service.ts:16
resize from=xxx echarts.directive.ts:37
resize echarts.directive.ts:40
ngOnInit() {
this.subscription = this.chartsService.chartChange.subscribe((str) => {
this.resizeChart(str);
});
this.chart = echarts.init(this.element.nativeElement, this.theme);
if (this.eChartsOptions) {
this.chart.setOption(this.eChartsOptions);
}
}
Here you set this.chart
after you subscribe to Subject
, while in resizeChart
you check if this.chart
is defined. 在这里,您在订阅
Subject
之后设置了this.chart
,而在resizeChart
您检查了this.chart
是否已定义。 It might fail just because it is still null at that point. 它可能仅因为此时仍为空而失败。 Try to set
this.chart
before subscribing to Subject
. 订阅
Subject
之前,请尝试设置this.chart
。
ok so i add this.resizeChart(str); 好的,所以我添加this.resizeChart(str); in ngOnInit method in EChartsDirective, and after each chart init, i have resize effect, so it's works for me
在EChartsDirective的ngOnInit方法中,并且在每次图表初始化之后,我都有调整大小的效果,所以它对我有用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.