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?
谢谢!
无论如何,如果是这种情况,那么你必须使用ngZone.run方法.
如果你想手动运行更改检测之外的东西,那么如果你想强制某些东西不要触发它,你应该使用runOutsideAngular.这不是您的用例,因此您可以安全地删除它.
The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that don’t require UI updates or error handling to be handled by Angular. Such tasks can be kicked off via runOutsideAngular and if needed,these tasks can reenter the Angular zone via run.
但另一方面,你提到 – 双向数据绑定对你不起作用(ngModel).我认为真正的问题是你更新现有对象的属性.这本身不会触发双向变化检测,这是ngZone.run工作的实际原因.如果是这种情况,那么changeRef.detectChanges将不起作用,您最好使用ApplicationRef并执行tick().或者不使用双向数据绑定并使用数据下降,事件上升模式.
constructor(private appRef: ApplicationRef){} getLocation(address: string): void { let mygc = new google.maps.Geocoder(); mygc.geocode({ 'address': address },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