我使用Geocoder API,当返回结果时,双向数据绑定不起作用。数据在视图内部不会刷新。如果我手动更改任何其他属性,数据会刷新...所以,我google(很多)并找到使用ngZone
的解决方案。这就是我所做的:
getLocation(address: string): void {
var mygc = new google.maps.Geocoder();
this._ngZone.runOutsideAngular(() => {
mygc.geocode({
'address': address
}, (results, status) => {
var data: any = results[0];
this._ngZone.run(() => {
this.myObject.myData = {
lat: data.geometry.location.lat(),
lng: data.geometry.location.lng()
};
});
});
});
}
所以我有几个问题:
ngZone
?文件很松散...... runOutsideAngular()
,所以使用它有什么意义?该示例还包括此函数调用,因此我也实现了它。但它没有它也可以工作...... myObject
吗?谢谢!
答案 0 :(得分:6)
如果我错了,有人会向我开枪,但就我所知,如果在加载zone.js
后下载外部脚本,则需要使用此功能。这意味着更改检测不会检测到该脚本内的任何更改。这是您稍后加载谷歌地图时发生的情况。也许....
无论如何,如果是这种情况,那么你必须使用ngZone.run
方法。
如果您想手动运行更改检测之外的某些内容,那么如果您想强制某些内容不能触发它,则应使用runOutsideAngular
。这不是您的用例,因此您可以安全地删除它。
此服务最常见的用途是在启动由一个或多个异步任务组成的工作时优化性能,这些异步任务不需要由Angular处理UI更新或错误处理。这些任务可以通过runOutsideAngular启动,如果需要,这些任务可以通过run重新进入Angular区域。
但另一方面,你提到 - 双向数据绑定对你不起作用(ngModel
)。我认为真正的问题是你更新现有对象的属性。这本身不会触发双向变化检测,这是ngZone.run
工作的实际原因。如果是这种情况,那么changeRef.detectChanges
将无效,您最好使用ApplicationRef
并执行tick()
。或者不要使用双向数据绑定并使用data goes down, events go up
模式。
constructor(private appRef: ApplicationRef){}
getLocation(address: string): void {
let mygc = new google.maps.Geocoder();
mygc.geocode({
'address': address
}, (results, status) => {
let data: any = results[0];
this.myObject.myData = {
lat: data.geometry.location.lat(),
lng: data.geometry.location.lng()
};
this.appRef.tick();
});
}
这显然有效,因为它与ngZone.run
没有区别。但是,未触发更改检测的主要原因是因为google.maps
使用自己的事件集/ addEventListener调用。这些事件不被zone.js
修改为猴子,因此不会在Angular区域中运行,这在逻辑上不会触发更改检测周期。
因此,您可以使用ngZone.run
选项或ApplicationRef.tick
来解决此问题。在哪里我认为ngZone.run
最有意义,因为它允许你(重新)进入角度区域,这正是你想要的。
关于NgZone
的“好”阅读,您可以查看api
答案 1 :(得分:1)
我简单地使用:
{{1}}