我正在使用 Ruby 3.2.2 开发 Rails 7.1.2 应用程序,并面临 Google 地图加载的间歇性问题。该地图有时会在 Firefox 中加载,但很少会在 Brave 中加载。尽管该操作的事件侦听器似乎正在执行,但刺激控制器操作似乎没有持续触发的问题。
首先,遵循一些过时的指南,我开始将此脚本添加到我的
app/javascript/application.js
window.dispatchMapsEvent = function(...args) {
const event = new CustomEvent("google-maps-callback", { detail: args });
window.dispatchEvent(event);
}
window.addEventListener("google-maps-callback", function(event) {
console.log("Google Maps API loaded");
})
这是我的
app/views/layouts/application.html.erb
的头:
<%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?key=#{Rails.application.credentials.google.api_key}&libraries=places&callback=dispatchMapsEvent",
defer: true,
async: true,
"data-turbolinks-eval": false
%>
在此代码中,我在浏览器控制台中收到此错误:
Uncaught (in promise) InvalidValueError: dispatchMapsEvent is not a function
虽然我遵循的大多数指南都建议这应该可行,但我认为错误是因为在执行回调时尚未加载
dispatchMapsEvent
函数,这就是为什么我将代码从 application.js
中取出并将其传递给布局内的脚本:
<script>
window.dispatchMapsEvent = function(...args) {
const event = new CustomEvent("google-maps-callback", { detail: args });
window.dispatchEvent(event);
}
window.addEventListener("google-maps-callback", function(event) {
console.log("Google Maps API loaded");
})
</script>
<%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?key=#{Rails.application.credentials.google.api_key}&libraries=places&callback=dispatchMapsEvent",
defer: true,
async: true,
"data-turbolinks-eval": false
%>
这似乎修复了提到的错误,因为 console.log 正确运行。
其次,我配置了一个 StimulusJS 控制器,如下所示:
views/folder/_some_partial.html.erb
<div
class="form-group"
data-controller="localizators"
data-action="google-maps-callback@window->localizators#initMap"
data-localizators-current-location-value="<%= current_location %>"
>
然后是
app/javascript/controllers/localizators_controller.js
:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
console.log('localizators controller connected');
}
initMap() {
console.log('map init');
}
}
消息“定位器控制器已连接”始终出现,但“地图初始化”在 Brave 浏览器中从未出现,有时在 Firefox 中出现(我不知道浏览器是如何实现的)
只是为了提供更多信息,我在我的开发环境中,如果我使用
bin/dev
或rails s
,效果是一样的。
如您所见,有两个问题我不知道它们是否相关。
我必须将代码作为 JS 脚本放置,因为使用推荐的配置,它似乎没有加载,并且 Stimulus 控制器操作仅有时会触发,即使 @window 中的事件似乎每次都会触发。
提前非常感谢您能给我的任何帮助。
您应该使用加载程序包:
https://www.npmjs.com/package/@googlemaps/js-api-loader
$ bin/importmap pin @googlemaps/js-api-loader
# make sure to have some height
<%= tag.div class: "h-[400px]",
data: {
controller: :localizators,
localizators_api_key_value: Rails.application.credentials.google.api_key,
localizators_current_location_value: {lat: -34.397, lng: 150.644}
}
%>
// app/javascript/controllers/localizators_controller.js
import { Controller } from "@hotwired/stimulus"
import { Loader } from "@googlemaps/js-api-loader"
// Connects to data-controller="localizators"
export default class extends Controller {
static values = {
currentLocation: Object,
apiKey: String,
}
connect() {
this.loader = new Loader({
apiKey: this.apiKeyValue,
version: "weekly",
// ...additionalOptions,
});
this.loader.load().then(async () => {
const { Map } = await google.maps.importLibrary("maps");
this.map = new Map(this.element, {
center: this.currentLocationValue,
zoom: 8,
});
});
}
}
https://developers.google.com/maps/documentation/javascript/load-maps-js-api#js-api-loader