[英]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.