Rails 7.1.2 + StimulusJS:在窗口上触发自定义事件后,Stimulus 控制器操作出现问题

问题描述 投票:0回答:1

我正在使用 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 中的事件似乎每次都会触发。

提前非常感谢您能给我的任何帮助。

javascript ruby-on-rails google-maps stimulusjs import-maps
1个回答
0
投票

您应该使用加载程序包:
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

© www.soinside.com 2019 - 2024. All rights reserved.