我是新手,并获得了Ionic框架的经验。虽然使用离子I进行编码但遇到了下面给出的一个问题
离子页面/模板代码
<ion-item>
<ion-label floating>{{ addressLabel }}</ion-label>
<ion-input name="address" id="addressField" type="text" required [(ngModel)]="address" #userAddress></ion-input>
</ion-item>
<div #locationMap id="locationMap"></div>
映射组件代码以更新标记丢弃时的地址值
onMarkerDrop(event) {
let latcurr = event.latLng.lat();
let longcurr = event.latLng.lng();
this.initializeCurrent(latcurr, longcurr);
let latLng = {lat: event.latLng.lat(), lng: event.latLng.lng()};
let infoWindow = new google.maps.InfoWindow();
infoWindow.open(this.map, this.marker);
infoWindow.close();
}
initializeCurrent(latcurr, longcurr) {
this.currgeocoder = new google.maps.Geocoder();
if (latcurr != '' && longcurr != '') {
let myLatlng = new google.maps.LatLng(latcurr, longcurr);
this.currgeocoder.geocode({'location': myLatlng}, (results, status) => {
if (status == google.maps.GeocoderStatus.OK) {
this.address = results[0].formatted_address;
// From above I am getting new location address on marker drop but that new address is not getting reflected at address input box.
console.log(this.address);
setTimeout(() => {
this.userAddress.setFocus();
this.keyboard.close();
}, 500);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
}
我没有得到我做错的事。请引导我通过正确的方式。谢谢。
答案 0 :(得分:1)
这是因为address
被传递给google.maps.Geocoder.prototype.geocode
的回调函数修改。回调是由Angular区域的<{1>}方法外部异步调度的。
Angular 使用 zone.js (Angular团队的一个副项目)来确定跨函数调用的逻辑调用上下文,以便更有效地处理更改检测。通过跟踪当前geocode
框架特定的异步编程抽象(仅由Angular使用),该框架减少了在95%快乐路径中重新渲染视图所需的次数。
在此上下文之外运行的代码不会触发视图的更新。
这是一种痛苦。
要解决此问题,您可能需要将代码包装在 Angular区域中。这将使更改检测在调用图中流动。
这是什么样的
zone
在遇到这种情况之后,人们常常开始将各种不相关的错误归因于区域内的问题,而这些问题实际上是无关的。
需要在上面创建显式区域的原因是框架与import {Component, NgZone} from '@angular/core';
@Component({
// boilerplate
})
export default class MapComponent {
constructor(readonly ngZone: NgZone) {}
initializeCurrent(latcurr, longcurr) {
if (!latcurr || !longcurr) {
return;
}
this.currgeocoder = new google.maps.Geocoder();
const latlng = new google.maps.LatLng(latcurr, longcurr);
this.currgeocoder.geocode({'location': latlng}, ([{formatted_address}], status) => {
if (status === google.maps.GeocoderStatus.OK) {
// Create a zone right here.
this.ngZone.run(() => {
// changes will be detected because we are in a zone.
this.address = formatted_address;
});
// The scope of a user-created zone should be as limited as possible.
console.log(this.address);
setTimeout(() => {
this.userAddress.setFocus();
this.keyboard.close();
}, 500);
}
else {
alert(`Geocode was not successful for the following reason: ${status}`);
}
});
}
}
调用您提供的回调的机制或时间之间没有逻辑连接。
大多数情况下,在编写良好的应用程序中接近100%,该区域将自动且隐式地传播,因为您的异步代码应该在Promises或Observables中。这些是框架所知道的规范异步原语(它将它们修补为挂钩...)。在Angular应用程序中总有一个区域,但您通常不会关心。
当您知道需要区域时,请务必小心使用区域。
如果你开始迷信地使用它们,你的应用程序将会变慢,你将无法理解正在发生的事情,你的代码将大大降低质量,你会疯了。
保守。
<强>附录:强>
正如我所提到的,编写良好的应用程序通常不会使用显式区域,而是使用Promises等标准API和Observables等半标准API。
虽然我倾向于赞成Promises,或者至少感觉我喜欢Angular,因为大多数Angular Observable都应该是Promises(XHR任何人?),在这种情况下提高抽象级别的正确方法实际上是使用Observables
原因是多次调用回调。
因此,我们实际上可以重写此代码,通过调整geocode
API来删除低级别且通常容易出错的区域使用。
以下是
geocode
令人瞩目的是代码变得多么简单。当observable用于表示信息的异步流时,它们可以非常优雅。毕竟,他们的设计代表了什么。当它们用于表示单数,甚至可能是同步值或同步流时,阻抗不匹配的程度令人作呕。
框架设计师,甚至更多的规范推动者,应该倾听Rx的创建者Erik Meijer并使用正确的工具来做正确的工作,而不是通过推送他们(双关语)给Observables一个坏名字意图?)代表数字import {Component} from '@angular/core';
import Rx from 'rxjs';
@Component({
// boilerplate
})
export default class MapComponent {
initializeCurrent(latcurr, longcurr) {
if (!latcurr || !longcurr) {
return;
}
this.currgeocoder = new google.maps.Geocoder();
const latlng = new google.maps.LatLng(latcurr, longcurr);
const addressObservable = new Rx.Observable(observer => {
this.currgeocoder.geocode({'location': latlng}, ([{formatted_address}], status) => {
observer.next({status, address: formatted_address});
});
});
addressObservable.do(() => {
setTimeout(() => {
this.userAddress.setFocus();
this.keyboard.close();
}, 500);
})
.subscribe(({status, address})=> {
if (status === google.maps.GeocoderStatus.OK) {
this.address = address;
}
else {
alert(`Geocode was not successful for the following reason: ${status}`)
}
});
}
}
的任务。
现在他们故意无视他,并像Reactive Streams规范一样制造绝对的垃圾。
但是Observables在他们被设计为惊人的东西时非常惊人。
分手:
我说这一切都是因为我老实说他讨厌我刚写的Rx版本。
Angular,围绕Reactive Streams规范的可笑的炒作,以及提出将技术标准化为JavaScript的方式(即&#34;它必须允许同步观察,因为它必须能够替换所有库和控制结构&#34; ),让我讨厌Rx,让我不想用任何东西,这是一件令人伤心的事情。