Не могу передать массив в chart.js, который получил данные из @Input - PullRequest
2 голосов
/ 12 июня 2019

Я пытаюсь понять, как передать данные из родительского компонента в дочерний компонент.
Более конкретно, я хочу передать массив из родительского компонента в дочерний компонент и использовать его какисточник данных для диаграммы.

Я использую Angular 8, mdbootstrap (который использует chart.js 2.5.0).Я прочитал кучу учебных пособий и выяснил, как передать содержимое из родительского компонента в дочерний компонент.Я могу получить доступ к строкам и т.д. из моего дочернего шаблона, используя экстраполяцию.
Моя проблема может быть связана с тем, как chart.js обрабатывает рендеринг своих диаграмм.
Я не уверен, в какой точке жизненного цикла он нуженего данные.Я попытался заполнить необходимые переменные в методе ngOnInit и методе AfterViewInit (не показано в коде), но это ничего не изменило.

Родительский компонент (statistics.component.ts)

export class StatisticsComponent implements OnInit {

  // business logic
  public isDataLoaded = false;
  public clientNumberList: string[] = new Array();
  public clientNumberCountList: number[] = new Array();

  // chart related stufff
  public chartLabel = 'User Statistics';

  public chartOptions: any = {
    responsive: true,
    maintainAspectRatio: false,
    scales: {
      xAxes: [{
        scaleLabel: {
          display: true,
          labelString: 'Client Number'
        }
      }],
      yAxes: [{
        scaleLabel: {
          display: true,
          labelString: 'Count'
        }
      }]
    }
  };

  constructor(private sdoUserStatisticsService: SdoUserStatisticsService) {}

  ngOnInit(): void {
    // get users and counts
    this.sdoUserStatisticsService.getUserStatistics().subscribe(users => {
      for (const user of users) {
        this.clientNumberList.push(user.clientNumber);
        this.clientNumberCountList.push(user.count);
      }
      this.isDataLoaded = true;
    })
      ;
  }
}

statistics.component.html

<div *ngIf="isDataLoaded">
<app-bar-chart [chartLabelInput]="chartLabel" [dataArrayInput]="clientNumberCountList" [labelArray]="clientNumberList" [chartOptionsInput]="chartOptions"></app-bar-chart>
</div>

Дочерний компонент (bar-chart.component.ts)

export class BarChartComponent implements OnInit{

  public chartType = 'bar';

  @Input() chartLabelInput: string;
  @Input() dataArrayInput: number[];

  public chartLabel: string;
  public dataArray: number[] = this.dataArrayInput;
  public chartDatasets: Array<any> = [
    {data: this.dataArray, label: this.chartLabel}
  ];

  @Input() labelArray: string[];
  public chartLabels: Array<any> = this.labelArray;

  @Input() chartOptionsInput: any;
  public chartOptions = this.chartOptionsInput;

  constructor() {}
  public chartClicked(e: any): void { }
  public chartHovered(e: any): void { }

  ngOnInit(): void {}
}

bar-chart.component.html

<canvas mdbChart
        [chartType]="chartType"
        [datasets]= "chartDatasets"
        [labels]="chartLabels"
        [options]="chartOptions"
        [legend]=true
        (chartHover)=chartHovered($event)
        (chartClick)=chartClicked($event)>
</canvas>

Я ожидаю, что смогу получить доступ к dataArrayInput в bar-chart.component.ts и тем самым передать эти данные на график,В действительности я могу получить доступ к этому массиву в методе ngOnInit (не показан в коде), но не использовать его для диаграммы.Я получаю следующую ошибку в консоли браузера:

ERROR TypeError: "newElm.data is undefined"
    Angular 10
        datasets
        getDatasets
        getChartBuilder
        refresh
        ngOnInit
        checkAndUpdateDirectiveInline
        checkAndUpdateNodeInline
        checkAndUpdateNode
        debugCheckAndUpdateNode
        debugCheckDirectivesFn
    View_BarChartComponent_0 BarChartComponent.html:1
    Angular 30
    RxJS 5
    Angular 9ERROR TypeError: "newElm.data is undefined"
    Angular 10
        datasets
        getDatasets
        getChartBuilder
        refresh
        ngOnInit
        checkAndUpdateDirectiveInline
        checkAndUpdateNodeInline
        checkAndUpdateNode
        debugCheckAndUpdateNode
        debugCheckDirectivesFn
    View_BarChartComponent_0 BarChartComponent.html:1
    Angular 30
    RxJS 5
    Angular 9

Я надеюсь, что кто-то может мне помочь:)

1 Ответ

1 голос
/ 12 июня 2019

Я думаю, что это проблема жизненного цикла Angular.Ваша проблема в том, как вы используете данные @Input.Вы явно хотите получить данные, которые поступают с dataArrayInput, но у вас нет доступа к ним правильно.

Переместите присваивание переменных, которые зависят от значений @Input, в пределах ngOnInitметод.Значение переменных @Input недоступно при создании компонента, поэтому при создании зависимых переменных вы инициализируете их с помощью undefined.

export class BarChartComponent implements OnInit {

  public chartType = 'bar';

  @Input() chartLabelInput: string;
  @Input() dataArrayInput: number[];

  public chartLabel: string;
  public dataArray: number[];
  public chartDatasets: Array < any > ;

  @Input() labelArray: string[];
  public chartLabels: Array < any > ;

  @Input() chartOptionsInput: any;
  public chartOptions;

  constructor() {}
  public chartClicked(e: any): void {}
  public chartHovered(e: any): void {}

  ngOnInit(): void {
    this.dataArray = this.dataArrayInput;
    this.chartDatasets = [{
      data: this.dataArray,
      label: this.chartLabel
    }];
    this.chartLabels = this.labelArray;
    this.chartOptions = this.chartOptionsInput;
  }
}

Посмотрите на это вопрос и этот вопрос .

...