【问题标题】:Using `google-maps-react` in Kotlin JS/React project在 Kotlin JS/React 项目中使用 `google-maps-react`
【发布时间】:2020-01-23 07:14:10
【问题描述】:

我正在尝试将google-maps-react 组件用作 Kotlin JS 项目的一部分,但遇到了一些问题,即它的使用方式如何映射到 Kotlin。到目前为止,我有以下 google-maps-react.kt 文件:

@file:JsModule("google-maps-react")

package org.example.kotlin.multiplatform.web


import react.*


@JsName("Map")
external val Map: RClass<RProps>


@JsName("GoogleApiWrapper")
external val GoogleApiWrapper: RClass<RProps>

如果我尝试使用Map,我会收到以下错误。有没有人试过这个或知道任何这样做的示例代码?我知道我至少需要设置 api 密钥(使用 GoogleApiWrapper),但似乎更普遍的问题是如何设置“google”对象(google={this.props.google} 是我在纯 javascript 使用中看到的)

未捕获的错误:您必须包含 google 属性

【问题讨论】:

    标签: kotlin kotlin-multiplatform kotlin-js


    【解决方案1】:

    我有两个文件定义如下

    //googlemap.kt

    @file:JsModule("@react-google-maps/api")
    
    package tz.co.asoft.ui.react.maps.google
    
    import react.Component
    import react.RProps
    import react.RState
    
    external interface LatLng {
        var lat: Double
        var lng: Double
    }
    
    external class GoogleMap : Component<GoogleMap.Props, RState> {
        interface Props : RProps {
            var id: String
            var center: LatLng
            var zoom: Int
            var mapContainerStyle: dynamic
        }
    
        override fun render(): dynamic
    }
    
    external class Marker : Component<Marker.Props, RState> {
        interface Props : RProps {
            var position: LatLng
        }
    
        override fun render(): dynamic
    }
    
    external class InfoWindow : Component<InfoWindow.Props, RState> {
        interface Props : RProps {
            var position: LatLng
        }
    
        override fun render(): dynamic
    }
    
    external class LoadScript : Component<LoadScript.Props, RState> {
        interface Props : RProps {
            var id: String
            var googleMapsApiKey: String
        }
    
        override fun render(): dynamic
    }
    
    external class Polyline : Component<Polyline.Props, RState> {
        interface Props : RProps {
            var path: Array<LatLng>
            var options: Options
            var onLoad: (polyline:dynamic)->Unit
        }
    
        interface Options {
            var strokeColor: String
            var strokeOpacity: Double
            var strokeWeight: Int
            var fillColor: String
            var fillOpacity: Double
            var clickable: Boolean
            var draggable: Boolean
            var editable: Boolean
            var visible: Boolean
            var radius: Int
            var paths: Array<LatLng>
            var zIndex: Int
        }
    
        override fun render(): dynamic
    }
    

    我还有一个文件可以让其 dsl 易于使用

    //dsl.kt

    package tz.co.asoft.ui.react.maps.google
    
    import kotlinext.js.js
    import kotlinext.js.jsObject
    import react.RBuilder
    import react.RHandler
    
    private fun RBuilder.loadScript(handler: RHandler<LoadScript.Props> = {}) = child(LoadScript::class) {
        attrs {
            id = "google-maps-script"
            googleMapsApiKey = "<your api key>"
        }
        handler()
    }
    
    private fun RBuilder.googleMap(handler: RHandler<GoogleMap.Props> = {}) = child(GoogleMap::class) {
        attrs {
            center = jsObject { lat = 0.0; lng = 0.0 }
            zoom = 13
            mapContainerStyle = js {
                height = "90%"
                width = "100%"
            }
        }
        handler()
    }
    
    fun RBuilder.polyLine(paths: Array<LatLng>, handler: RHandler<Polyline.Props> = {}) = child(Polyline::class) {
        attrs {
            options = jsObject {
                strokeColor = "#FF0000"
                strokeOpacity = 0.8
                strokeWeight = 2
                fillColor = "#FF0000"
                fillOpacity = 0.35
                clickable = false
                draggable = false
                editable = false
                visible = true
                radius = 30000
                zIndex = 1
            }
            options.paths = paths
        }
        attrs.path = paths
        handler()
    }
    
    fun RBuilder.marker(handler: RHandler<Marker.Props> = {}) = child(Marker::class) {
        attrs { position = jsObject { lat = 0.0; lng = 0.0 } }
        handler()
    }
    
    fun RBuilder.infoWindow(handler: RHandler<InfoWindow.Props> = {}) = child(InfoWindow::class) {
        attrs { position = jsObject { lat = 0.0; lng = 0.0 } }
        handler()
    }
    
    fun RBuilder.map(handler: RHandler<GoogleMap.Props> = {}) = loadScript {
        googleMap {
            handler()
        }
    }
    
    fun Array<Double>.toLatLng() = jsObject<LatLng> {
        lat = get(0)
        lng = get(1)
    }
    

    现在我可以在我的 react 项目中使用 lib 作为

    div{
        map {
            marker {
                attrs { position = jsObject { lat = 0.0; lng = 0.0 } }
            }
        }
    }
    

    希望对你有帮助

    【讨论】:

    • 即使我添加@file:JsModule("@react-google-maps/api") @file:JsNonModule 我得到:When accessing module declarations from UMD, they must be marked by both @JsModule and @JsNonModule。有什么想法吗?
    猜你喜欢
    • 2018-09-14
    • 2021-04-13
    • 2018-05-03
    • 2020-08-02
    • 2021-09-28
    • 1970-01-01
    • 2018-11-18
    • 2018-02-19
    • 2018-05-03
    相关资源
    最近更新 更多