我知道我不是第一个问这个问题的人,但我在之前的问题中找不到答案.我把这个放在一个组件里

<div class="col-sm-5">
    <laps
        [lapsData]="rawLapsData"
        [selectedTps]="selectedTps"
        (lapsHandler)="lapsHandler($event)">
    </laps>
</div>

<map
    [lapsData]="rawLapsData"
    class="col-sm-7">
</map>

在控制器中,rawLapsdata不时发生变异.

laps中,数据以表格格式输出为HTML.每当rawLapsdata改变时,这种情况就会改变.

我的map组件需要使用ngOnChanges作为触发器在谷歌 map 上重新绘制标记.问题是,当rawLapsData在父对象中发生变化时,ngOnChanges不会触发.我能做什么?

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();
    }

Update: ngOnChanges不工作,但看起来lapsData正在更新.ngOnInit中有一个用于zoom 更改的事件侦听器,它也调用this.drawmarkers.当我改变zoom 时,我确实看到了标记的变化.所以唯一的问题是,在输入数据更改时,我没有收到通知.

在家长中,我有这样一行.(回想一下,这种变化反映在圈数上,而不是map圈).

this.rawLapsData = deletePoints(this.rawLapsData, this.selectedTps);

请注意,this.rawLapsData本身就是一个指向大型json对象中间的指针

this.rawLapsData = this.main.data.TrainingCenterDatabase.Activities[0].Activity[0].Lap;

推荐答案

rawLapsData继续指向同一数组,即使您修改了数组的内容(例如,添加项、删除项、更改项).

在变更检测期间,当Angular判断组件的输入属性是否发生变更时,它(基本上)使用===进行脏检.对于数组,这意味着数组引用(仅)是脏判断的.因为rawLapsData数组引用没有改变,所以不会调用ngOnChanges().

我可以想出两种可能的解决方案:

  1. 实现ngDoCheck()并执行自己的更改检测逻辑,以确定数组内容是否已更改.(生命周期钩子文档有an example个.)

  2. 每当您对数组内容进行任何更改时,都会将新数组分配给rawLapsData.则将调用ngOnChanges(),因为数组(引用)将显示为更改.

在你的回答中,你想出了另一个解决方案.

在这里重复一些关于OP的 comments :

我仍然不明白laps怎么能接受这个变化(肯定它使用的是与ngOnChanges()本身相当的东西?)而map不能.

  • laps组件中,代码/模板在lapsData数组中的每个条目上循环,并显示内容,因此在显示的每个数据段上都有Angular 绑定.
  • 即使ANGLING没有检测到组件输入属性的任何更改(使用===判断),它仍然(默认情况下)脏判断所有模板绑定.当其中任何一个更改时,ANGLING将更新DOM.这就是你所看到的.
  • maps组件在其模板中很可能没有任何到其lapsData输入属性的绑定,对吗?这就可以解释不同之处了.

Note that lapsData in both components and rawLapsData in the parent component all point to the same/one array. So even though Angular doesn't notice any (reference) changes to the lapsData input properties, the components "get"/see any array contents changes because they all share/reference that one array. We don't need Angular to propagate these changes, like we would with a primitive type (string, number, boolean). But with a primitive type, any change to the value would always trigger ngOnChanges() – which is something you exploit in your answer/solution.

到目前为止,您可能已经了解到,对象输入属性具有与数组输入属性相同的行为.

Angular相关问答推荐

Angular :仅当 Select 第一个日期时才显示第二个日期字段

Angular 和PrimeNg文件Uploader:渲染元件时如何显示选定文件的列表?

如何动态呈现组件并以Angular 访问它们的方法?

TransLoco合并本地和服务器端转换对象

声明Angular material 中按钮的自定义 colored颜色

Angular -移位在2个示波器中读取

ANGLING HTTP.GET()返回包含数据的数组

Angular-每2个流式传输多个HTTP调用

Angular Mat Select 显示键盘焦点和鼠标悬停焦点的问题

MatTooltip 显示在 html 原生对话框下方

显示 1 个数据而不是所有 ngFor - Angular 11

可观察的等待直到另一个可观察的值

Angular 2如何使用路由和location.go()检测后退按钮按下?

如何将新的 FormGroup 或 FormControl 添加到表单

读取文件并解析其内容

@angular/platform-b​​rowser 与 @angular/platform-b​​rowser-dynamic

angular2中的httpinterceptor类似功能是什么?

Angular 2:为什么在检索路由参数时使用 switchMap?

Angular 2中不同页面的多种布局

ng add 与 npm install 在 Angular 6 中的区别