簡體   English   中英

Angular 子組件無法識別輸入更改

[英]Angular child component doesnt recognize input changes

您好,我使用父子通信。 在父級,我有表示圖形數據的數組。 演示

我的問題是,當我更改數組中的一項時,我不會觸發子組件應用程序更改。 在演示中,我創建了不起作用的示例。 當我單擊更新時,我想更新子組件圖。

我的子組件

import { Component, OnInit, Input, OnChanges } from "@angular/core";
import * as Highcharts from "highcharts";
import { ChartService } from "./chart.service";

@Component({
  selector: "hello",
  template: `
    <highcharts-chart
      [Highcharts]="Highcharts"
      [options]="options"
      [oneToOne]="true"
      [update]="updateFromInput"
      style="width: calc(100% ); height: calc(100% - 17px); display: block;margin-top:15px;overflow: auto !important;"
    >
    </highcharts-chart>
  `,
  styles: [
    `
      h1 {
        font-family: Lato;
      }
    `
  ]
})
export class HelloComponent implements OnInit, OnChanges {
  innerHeight: any;
  innerWidth: any;

  @Input() data: any;

  Highcharts: typeof Highcharts = Highcharts;
  updateFromInput = false;
  options: any;

  constructor(private chart_service: ChartService) {
    this.innerHeight = window.screen.height;
    this.innerWidth = window.screen.width;
  }

  onResize(event) {
    this.innerWidth = event.target.innerWidth;
    this.update();
  }

  ngOnInit() {
    this.update();
  }

  ngOnChanges() {
    console.log(this.data);
    console.log("değişti");
    this.update();
  }

  update() {
    var series = this.chart_service.groupBy(
      this.data.LINE.DATA,
      "GRUP",
      "line"
    );
    var categories = this.chart_service.ArrNoDupe(
      this.data.LINE.DATA.map(x => x.NAME)
    );
    let isLegend = series.length > 1 ? true : false;
    var size = this.innerWidth / (12 / this.data.SIZE) - 30;
    if (this.innerWidth <= 992) {
      size = this.innerWidth - 30;
    }
    this.options = {
      title: { enabled: false, text: "" },
      credits: { enabled: false },
      legend: { enabled: true },
      tooltip: { hideDelay: 0, outside: true, shared: true },
      plotOptions: {
        line: { dataLabels: { enabled: !isLegend }, enableMouseTracking: true }
      },
      yAxis: { title: { enabled: false } },
      xAxis: { categories: categories },
      series: series
    };
  }
}

在你的 app.component.ts 中:

filter(id) {
    this.reports.filter(x => x.ID == id)[0] = {
      ID: 3233.0,
    ...
   }
}

Array.prototype.filter不會改變給定的數組,而是返回一個具有過濾屬性的新數組。 您必須重新分配此值以使 Angular 更改檢測檢測到這個新數組:

filter(id) {
    this.reports = this.reports.filter(x => x.ID == id)[0] = {
      ID: 3233.0,
    ...
   }
}

看起來您的代碼中有三個錯誤:

  • 你的@Input() getter/setter 被切換
@Input() set data(data: any) {
  this._param = data;
}

get data(): any {
  return this._param;
}
  • 您的過濾器實際上沒有過濾任何東西(至少就我從數據中看到的而言)
  • 需要通知您的*ngFor ,您的數據已更改 - 為此,您可以實現ngOnChanges生命周期掛鈎並將報告的SimpleChanges中的最新值分配給成員變量報告

正如@code-gorilla提到的,它不起作用,因為您沒有改變reports數組,因此未檢測到更改=您的圖表未更新。

修改您的代碼后,它會改變我能夠使其工作的reports ,您可以在我在下面附加的演示中找到更多詳細信息。

  filter(id) {
    const updatedReport = (this.reports.filter(
      x => x.CHART_ITEM_ID == id
    )[0] = { ... } 
    });

    this.reports[0] = updatedReport;
  }

現場演示:
https://stackblitz.com/edit/angular-7yr5qg?file=src%2Fapp%2Fapp.component.ts

通常,當數據對象源發生變化時會觸發OnChanges ,但不會在數據發生變異時觸發。 為了使數組調用OnChanges ,它必須以不可變的方式更新。 本文的示例中,slice 是一個不可變函數——意味着它不會改變原始數組,而 splice 是一個可變函數——意味着它會改變原始數組。

因此,在您的示例中,為了調用 onChanges,您需要使用不可變函數,例如map而不是filter

在您的特定情況下,您似乎並不真的想使用filter ,因為您只需要與謂詞匹配的第一個元素。 你真的應該使用find來代替。 有一個單獨的report屬性,然后讓你的函數調用report = this.reports.find(x => x.CHART_ITEM_ID == id) ,並將report綁定到孩子

在上面的有用答案之后,我首先將索引分配給變量,然后使用如下代碼演示的索引進行更新

 let index=this.reports.findIndex( x => x.CHART_ITEM_ID == id ); 
  this.reports[index]= ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM