使用ScalaJS + Akka时未捕获LeafletJS映射单击事件

时间:2018-01-17 22:08:46

标签: leaflet akka scala.js

我正在使用LeafletJS显示地图的ScalaJS + Akka网络应用程序。这一切都很好,除非我试图捕捉LeafletJS地图的click事件。

创建地图并添加图块层都可以很好地工作:

def worldMap(mapDiv: String): LMap = {
  // Show map of whole world
  val mapRef = L.map(mapDiv, LMapOptions.zoom(worldZoomLevel).center(startPos))

  // Add click event handler to map
  mapRef.on("click", (msg: dom.MouseEvent) => StageManager.countryMapActor ! msg)

  val queryStr = (
    for (p <- mbQueryParams.keys)
      yield s"$p=${mbQueryParams.get(p).get}"
    ).mkString("?", "&", "")

  // Add map tile layer
  L.tileLayer(
    mapBoxEndpoint + queryStr,
    TileLayerOptions.
      id("mapbox.streets").
      maxZoom(19).
      attribution(
        """Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors,
          |<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>,
          |Imagery © <a href="http://mapbox.com">Mapbox</a>""".stripMargin)
  ).addTo(mapRef)

  mapRef
}

代码行

mapRef.on("click", (msg: MouseEvent) => StageManager.countryMapActor ! msg)

编译并运行正常,但是从不调用侦听此事件的相应Akka actor。

侦听此事件的actor包含以下内容:

class CountryMapActor extends Actor {
  def receive = {
    // SNIP
    case evt: MouseEvent =>
      if (evt.hasOwnProperty("latlng")) {
        // do something with lat/lng...
      }
  }
}

但是从未收到此消息 - 无论我使用dom.Event还是dom.MouseEvent

我已尝试将事件类型更改为LeafletMouseEvent(根据leaflet documentation),但是演员上方的receive方法无法使用错误消息进行编译isInstanceOf[com.felstar.scalajs.leaflet.LeafletMouseEvent] not supported because it is a raw JS trait

我不想在地图上添加标记,因为整个观点是用户可以点击地图上的任意位置来检索有关该位置的信息。

如何通过ScalaJS获取LeafletJS地图点击事件的任何想法?

由于

Chris W

2 个答案:

答案 0 :(得分:1)

好的,解决了......

首先,为了能够提取相关的地理信息,添加到Map对象的click事件处理函数必须采用LeafletMouseEvent类型的参数。

事件名称为click,可以使用LMapEvent.click.toString进行硬编码,也可以更加健壮。

mapRef.on(LMapEvent.click.toString, (evt: LeafletMouseEvent) =>
  StageManager.countryMapActor ! MessageBox.MapClick(new MapLocation(evt.latlng))
)

其次,类型LeafletMouseEvent的事件对象不能作为消息直接发送给Akka actor,因为它只是一个特征。  因此,首先必须将相关数据从事件对象卸载到某个具体类的实例中(在我的例子中,我只是编写了一个名为MapLocation的东西)

class MapLocation(latlng: leaflet.LatLng) {
  val lat:Double = latlng.lat
  val lng:Double = latlng.lng
}

最后,监听此消息的Akka actor收到类型为MapLocation的消息,而不是某种事件类型的消息。在我的例子中,各个actor使用的所有消息都被定义为一个名为MessageBox的对象中的一组案例类;因此,在上面的代码中,我发送的是MessageBox.MapClick(new MapLocation(evt.latlng))

类型的消息

现在一切正常......

BTW,我正在使用的LeafletJSfaçcade由Dino Fancellu提供

答案 1 :(得分:0)

事件名称最有可能是"click"而不是"onclick"