我知道我不是第一个问这个问题的人,但我在前面的问题中找不到答案。我在一个组件中有这个
<div class="col-sm-5"> <laps [lapsData]="rawLapsData" [selectedTps]="selectedTps" (lapsHandler)="lapsHandler($event)"> </laps> </div> <map [lapsData]="rawLapsData" class="col-sm-7"> </map>
在控制器rawLapsdata中会不时发生变异。
rawLapsdata
在laps中,数据HTML以表格格式输出。这会随着rawLapsdata变化而变化。
laps
HTML
我的map组件需要ngOnChanges用作触发器来重绘 Google 地图上的标记。问题是当父级发生更改ngOnChanges时不会触发。rawLapsData我能做些什么?
map
ngOnChanges
rawLapsData
import {Component, Input, OnInit, OnChanges, SimpleChange} from 'angular2/core'; @Component({ selector: 'map', templateUrl: './components/edMap/edMap.html', styleUrls: ['./components/edMap/edMap.css'] }) export class MapCmp implements OnInit, OnChanges { @Input() lapsData: any; map: google.maps.Map; ngOnInit() { ... } ngOnChanges(changes: { [propName: string]: SimpleChange }) { console.log('ngOnChanges = ', changes['lapsData']); if (this.map) this.drawMarkers(); }
更新: ngOnChanges不起作用,但看起来好像lapsData正在更新。在 中ngOnInit是一个用于缩放更改的事件侦听器,它也调用this.drawmarkers. 当我更改缩放时,我确实看到标记发生了变化。所以唯一的问题是我在输入数据更改时没有收到通知。
lapsData
ngOnInit
this.drawmarkers
在父母中,我有这条线。(回想一下,变化反映在圈数中,但不反映在 中map)。
this.rawLapsData = deletePoints(this.rawLapsData, this.selectedTps);
请注意,this.rawLapsData它本身就是一个指向大型 json 对象中间的指针
this.rawLapsData
this.rawLapsData = this.main.data.TrainingCenterDatabase.Activities[0].Activity[0].Lap;
rawLapsData继续指向同一个数组,即使您修改了数组的内容(例如,添加项目、删除项目、更改项目)。
在更改检测期间,当 Angular 检查组件的输入属性是否更改时,它(本质上)===使用脏检查。对于数组,这意味着(仅)对数组引用进行了脏检查。由于rawLapsData数组引用没有改变,ngOnChanges()因此不会被调用。
===
ngOnChanges()
我可以想到两种可能的解决方案:
实现ngDoCheck()并执行您自己的更改检测逻辑以确定数组内容是否已更改。(Lifecycle Hooks 文档有一个例子。)
ngDoCheck()
rawLapsData每当您对数组内容进行任何更改时,都会分配一个新数组。然后ngOnChanges()将被调用,因为数组(引用)将作为更改出现。
在您的回答中,您提出了另一种解决方案。
在此处重复一些关于 OP 的评论:
我仍然看不到如何laps接受更改(肯定它必须使用与ngOnChanges()自身等效的东西?)而map不能。
maps
请注意,lapsData在两个组件和rawLapsData父组件中都指向同一个/一个数组。因此,即使 Angular 没有注意到lapsData输入属性的任何(引用)更改,组件“获取”/查看任何数组内容也会更改,因为它们都共享/引用该数组。我们不需要 Angular 来传播这些更改,就像我们使用原始类型(字符串、数字、布尔值)一样。但是对于原始类型,对值的任何更改都会触发ngOnChanges()——这是您在答案/解决方案中利用的东西。
正如您现在可能发现的那样,对象输入属性与数组输入属性具有相同的行为。