我知道我不是第一个问这个的,但是我在前面的问题中找不到答案。我有一个组件
<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
作为触发器在Google 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();
}
更新:ngOnChanges不工作,但看起来像是正在更新lapsData。在ngInit中是一个用于缩放更改的事件侦听器,它还调用this.drawmarks
。当我改变缩放时,我确实看到了标记的变化。所以唯一的问题是我在输入数据更改时没有得到通知。
在父母,我有这一行。(回想一下变化体现在laps上,而不是在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()
。
我能想到两种可能的解决办法:
>
实现ngdocheck()
并执行您自己的更改检测逻辑以确定数组内容是否已更改。(Lifecycle Hooks文档有一个示例。)
每当对数组内容进行任何更改时,为rawlapsdata
分配一个新数组。然后将调用ngonchanges()
,因为数组(引用)将显示为更改。
在你的回答中,你想出了另一种解决方案。
这里重复一些关于OP的评论:
我仍然不明白laps
如何能够发现更改(肯定是使用了与ngonchanges()
本身等价的东西?)而map
则不能。
laps
组件中,您的代码/模板在lapsdata
数组中的每个条目上循环,并显示内容,因此在显示的每段数据上都有角度绑定。===
检查),它仍然(默认情况下)脏检查所有模板绑定。当其中任何一个发生变化时,Angular将更新DOM。这就是你看到的。maps
组件的模板中可能没有任何绑定到其lapsdata
输入属性,对吗?这就解释了两者的区别。请注意,两个组件中的lapsdata
和父组件中的rawlapsdata
都指向同一个/一个数组。因此,即使Angular没有注意到lapsdata
输入属性的任何(引用)更改,组件“获得”/看到任何数组内容更改,因为它们都共享/引用了一个数组。我们不需要Angular来传播这些更改,就像使用基元类型(字符串、数字、布尔)一样。但是对于基元类型,对值的任何更改都会触发ngonchanges()
-这是您在答案/解决方案中利用的东西。
现在您可能已经了解到,对象输入属性具有与数组输入属性相同的行为。
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除: var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的 对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用Vue.set(object, key, value)方法向嵌
我需要更新嵌套在我的用户文档中的一个字段,该字段包含一个part对象数组,以添加新的part。一个part对象如下所示: 所以这意味着$addToset对我的情况没有好处...现在我不知道该怎么办。
问题内容: 我需要在ASP .Net应用程序中实现“未保存的更改”提示。如果用户修改了Web表单上的控件,并试图在保存之前导航离开,则将出现提示,警告他们尚未保存更改,并为他们提供取消并保留在当前页面上的选项。如果用户未触摸任何控件,则不应显示该提示。 理想情况下,我想用JavaScript实现此功能,但是在我开始滚动自己的代码之前,是否有任何现有的框架或推荐的设计模式来实现这一目标?理想情况下,
问题内容: 我试图使用makemigrations命令在现有应用程序中创建迁移,但输出“未检测到更改”。 通常,我使用命令创建新应用,但在创建该应用时并未将其用于该应用。 调试后,我发现它没有创建迁移,因为应用程序中缺少软件包/文件夹。 如果不存在该文件夹,还是创建丢失的文件夹,会更好吗? 问题答案: 要为应用创建初始迁移,请运行并指定应用名称。将创建迁移文件夹。 你的应用必须首先包含(在sett