2017-09-26 87 views
0

我有Directive其中有Subscription调整大小的图表Angular4 ngOnInit rxjs /主题不工作

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:

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

和组件在那里我打电话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 :

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') 
    ); 
    } 
} 

和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> 

所以,问题是,当我在浏览器或f5refreshupdateCharts方法调用中HomeComponentchartChange主题没有工作我猜的,因为在EChartsDirective订阅没不调用方法resizeChart,并且此问题仅在refreshf5之后。 如果我点击Resize btn,一切正常。

,所以我不知道为什么,但subscriptionEChartsDirectiverefreshf5后没有援引resizeChart

任何想法为什么会发生?

UPDATE: 而唯一的问题与chart2,我加chart1,我手动init(无指令)在HomeComponent -> ngOnInit,当我打电话

setTimeout(() => { 
      chart.resize(); 
      }, 500); 

它的工作原理,但只能当然,问题以认购,但仍然)

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

没什么resizeChart改变

登录后,点击后browser refreshF5

from=home-123 

登录到调整BTN

from=xxx  chart.service.ts:16 
resize from=xxx echarts.directive.ts:37 
resize   echarts.directive.ts:40 

回答

1
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); 
    } 
    } 

这里设置this.chart您订阅Subject,而你检查是否定义了。它可能会失败,因为它在那时仍然是空的。在订阅Subject之前尝试设置this.chart

+0

没有帮助,你能举个例子吗? – user2870934

+0

在resizeChart的控制台中记录什么?它甚至被称为? – pop

+0

没有来自resizeChart的日志,好吧,我添加this.resizeChart(str);在EChartsDirective中的ngOnInit方法中,并且在每个图表初始化之后,我都调整了大小,所以它适用于我 – user2870934

0

好吧,所以我补充一点。resizeChart(STR);在EChartsDirective中的ngOnInit方法,并在每个图表初始化后,我有调整大小的效果,所以它适用于我