Angular 4 HTML 模板等待 ngOnInit()

Angular 4 HTML template waiting on ngOnInit()

我正在尝试使用 ng2-charts 库在 Angular 4 中创建一系列图表。出于某种原因,我无法让图表 <canvas> 等到 ngOnInit(),它负责加载图表数据。相反,它似乎在 ngOnInit() 之前读取了一些数据,然后读取了其余数据:.

我的组件 HTML 是这样的:

<div style="width: 40%;">
  <div class="col-md-6">
    <button (click)="changeChartType('bar')" class="btn btn-default">Bar Chart</button>
    <button (click)="changeChartType('pie')" class="btn btn-default">Pie Chart</button>
    <button (click)="changeChartType('polarArea')" class="btn btn-default">Polar Chart</button>
  </div>
  <canvas
      baseChart
      [chartType]="chartType"
      [data]="myChartData"
      [labels]="chartLabels"
      [options]="chartOptions"
      [legend]="true"
      (chartClick)="onChartClick($event)">
  </canvas>
</div>

TypeScript 文件是这样的:

import { Component, Input, OnInit, NgZone } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SelectedStatusConstants } from '../../constants/selected-status.constants';
import { SkillsetService } from '../../services/skillset.service';
import { ChartScale } from '../../chart-scale';

@Component({
  selector: 'app-chart',
  templateUrl: './chart.component.html',
  styleUrls: ['./chart.component.css']
})

export class ChartComponent implements OnInit{
  @Input() selectedStatus : string = '';

  public static readonly chartTypes = {
    BAR : 'bar',
    PIE : 'pie',
    POLAR_AREA : 'polarArea'
  }

  private static SKILL_INFO : Map<String, any>;

  private skillID : number;

  chartType = ChartComponent.chartTypes.BAR;

  chartOptions : {[k: string]: any} = {
    type : this.chartType,
    legend : {
      display : false
    },
    xAxes:[
      {
        ticks: {
          autoSkip:false
        }
      }
    ],
    scales : new ChartScale()
  };

  chartData = [
    { data: [330, 600, 260, 700], label: 'Account A' },
    { data: [120, 455, 100, 340], label: 'Account B' },
    { data: [45, 67, 800, 500], label: 'Account C' }
  ];

  myChartData = [330, 600, 260, 700];

  chartLabels = [];

  constructor(private skillsetService : SkillsetService, 
    private route : ActivatedRoute,
    private zone : NgZone) {
      // setup SKILL_INFO
      if (!ChartComponent.SKILL_INFO) {
        ChartComponent.SKILL_INFO = new Map();
        ChartComponent.SKILL_INFO.set(SelectedStatusConstants.TRAINING, 6);
        ChartComponent.SKILL_INFO.set(SelectedStatusConstants.OPEN, 7);
        ChartComponent.SKILL_INFO.set(SelectedStatusConstants.SELECTED, 8);
        ChartComponent.SKILL_INFO.set(SelectedStatusConstants.CONFIRMED, 9);
        ChartComponent.SKILL_INFO.set('', 0);
      }
    }

    ngOnInit(): void {
      // get skillID
      this.skillID = ChartComponent.SKILL_INFO.get(this.selectedStatus) || 0;
      if (!this.skillID)
      {
        this.skillID = Number(this.route.snapshot.paramMap.get('id'));
      }
      // get the skillset data here
      this.skillsetService.getSkillsetsForStatusID(this.skillID).subscribe((res) => {
        // copy in the raw data into local variable
        let skillsets : Array<any> = res.data;
        // map() that variable into chartData,chartLabels
        this.myChartData = skillsets.map((obj) => {if (obj.count) return obj.count}).filter((val) => val !== undefined);
        this.chartLabels = skillsets.map((obj) => {if (obj.count) return obj.name}).filter((val) => val !== undefined);
        console.log("this.chartData == %s", JSON.stringify(this.myChartData, null, '\t'))
        console.log("this.chartLabels == %s", JSON.stringify(this.chartLabels, null, '\t'))
      });
    }

  onChartClick(event) {
    console.log(event);
  }

  changeChartType(type : string) {
    this.chartType = type;
    // changing some chartOptions pre-emptively
    this.chartOptions.type = type;
    switch (type) {
      // if type is either PIE or POLAR_AREA...
      case ChartComponent.chartTypes.PIE:
      case ChartComponent.chartTypes.POLAR_AREA:
        // ... we're displaying the chart legend and on the right of the container
        this.chartOptions.legend = {
          display : true,
          position: 'right'
        };
        // ... and getting rid of the scales ...
        if (this.chartOptions.scales) delete this.chartOptions.scales;
        break;
      // otherwise, for BAR charts...
      case ChartComponent.chartTypes.BAR:
        // ...we give no legend...
        this.chartOptions.legend = {
          display:false
        };
        // ...but give scales...
        this.chartOptions.scales = new ChartScale();
        break;
    }
    // it's a mock, for right now
    return type;
  }

}

它是这样显示的,但显示不同的图表效果很好:

并导航回组件似乎解决了问题,尽管条形图只有一种颜色:

我该如何解决这个问题?

添加 *ngIf 以检查数据集是否已加载

   <canvas *ngIf="datasets.length > 0"></canvas>