gpt4 book ai didi

javascript - 在 Angular 网站主页上调用自定义指令之前如何等待 google maps API 脚本返回

转载 作者:行者123 更新时间:2023-12-05 05:45:48 26 4
gpt4 key购买 nike

问题 - 在解析和加载谷歌地图 API 脚本后,谷歌地图自动完成下拉菜单无法在我的网站主页上运行。我在我的网站主页上遇到了我认为是竞争条件的情况,在顶部导航栏内的输入字段中,我在 custom autocomplete directive 中使用谷歌地图自动完成功能。 .自动完成下拉菜单不起作用的问题仅发生在移动设备上,台式机似乎没问题。我正在使用 '<script async defer...' 来防止等待脚本完成 DL'ing 来 prase 页面,所以我相信输入标签上的指令(包含自动完成的地方)被解析和呈现并被在脚本有时间完成加载之前实例化。结果,下拉列表在主页(仅限移动设备)上不起作用,其他页面都很好。

解决方案 1 - 删除“async defer”并同步加载,这解决了问题并且加载速度似乎非常快,但不是我理想的解决方案,尤其是对于我的网站主页。也许有人可以在解析页面之前在这里谈谈他们对同步加载 map API 的想法?

解决方案 2 - 异步加载 Google API 脚本并等待它完成,然后在指令中实例化地点自动完成对象和监听器。我想使用内置的回调功能,但不确定这是否有效,但这似乎是我应该尝试的途径...

这是我的尝试,但我需要帮助,因为我有错误。

Index.html - 伪代码

<html lang="en">
<head>
// other tags left out for brevity
<script src="./index.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=secret-key&libraries=places&callback=initMap" async defer></script>
</head>
<body>
<app-root></app-root>
</body>
</html>

Mainpage.html - 为简洁而创建的伪代码

<nav class="navbar navbar-light bg-light fixed-top">
<form class="form-inline">
<input appGooglePlaces class="form-control google-place-input" placeholder="Search" aria-label="Search" (onSelect)="fetchResults($event)">
</form>
</nav>

Index.ts - 我创建此文件是为了从脚本接收回调“initMap”,但未被调用并收到错误提示。

localhost/:1 Uncaught (in promise) fe {message: 'initMap is not a function', name: 'InvalidValueError', stack: 'Error\n at new fe (https://maps.googleapis.com/m…GUFa3DM&libraries=places&callback=initMap:197:125'}

function initMap(): void {
// not being hit
console.log('callback hit');
// instantiate the objects inside the 'appGooglePlaces' directive so we can use it
}
export {
initMap
};

仅供引用 - 我可以将回调函数嵌入到 index.html 文件中的脚本标记内,但是我无法调用其他 Angular 组件、服务、指令等。这可能吗在 Angular 中?

appGooglePlaces - 指令

import {
Directive,
ElementRef,
OnInit,
Output,
EventEmitter,
Input
} from '@angular/core';
import {
Address
} from '../shared/models/address';

@Directive({
selector: '[appGooglePlaces]'
})
export class GooglePlacesDirective implements OnInit {
private element: HTMLInputElement;
private autocomplete: google.maps.places.Autocomplete;
@Output() onSelect: EventEmitter < any > = new EventEmitter();
@Input() countrySelected = '';

constructor(private elRef: ElementRef) {
this.element = elRef.nativeElement;
}

ngOnInit() {

this.autocomplete = new google.maps.places.Autocomplete(this.element);

google.maps.event.addListener(this.autocomplete, 'place_changed', () => {

const place = this.autocomplete.getPlace();

if (place.name === '') {
return false;
}

const address = new Address();
// address processing left out for brevity
this.onSelect.emit(address);

});

}



}

最佳答案

我想我有一些可能对您有用的东西,就像问题中的“解决方案 2”...

Here is a working example它的工作前提是 index.html 中有一个全局回调,它将是来自 map 的回调命中。

<script>
console.log('calling globalMethod in 5 seconds...');
window.setTimeout(() => {
window.globalMethod('THIS IS A NEW VALUE FROM OUTSIDE ANGULAR');
}, 5000);
</script>

然后在 app.component(或任何你想要的组件)的构造函数中定义了一个窗口方法。

constructor(public zone: NgZone) {
(window as any).globalMethod = (someValue) => {
console.log('globalMethod >> ' + someValue);
this.zone.run(() => (this.name = someValue));
};
}

这行代码将强制 Angular 运行从 Angular 外部发生的更新 this.zone.run(() => (this.name = someValue));

所以我在您的应用程序中的建议是您可以在此处设置一个 *ngIf 变量,然后它会渲染您的 map 。

this.zone.run(() => (this.showMap = true));

关于javascript - 在 Angular 网站主页上调用自定义指令之前如何等待 google maps API 脚本返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71288988/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com