如何为通过<script>加载的Google Maps JavaScript API创建Reason绑定?
如何为Google Maps JavaScript API创建Reason绑定(非NPM、回调式加载)
当然可以实现,而且效果和原生JS完全一致——毕竟Reason最终会编译成标准JavaScript,和原生写法的执行逻辑是互通的。我给你一步步拆解具体实现方式:
1. 先在HTML中配置Google Maps API加载
和原生JS一样,在<body>底部添加API的script标签,指定callback参数为我们后续要在Reason中定义的全局函数名(比如initGoogleMaps):
<!-- 替换YOUR_API_KEY为你的真实密钥 --> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initGoogleMaps" async defer></script>
2. 在Reason中定义全局回调函数
Google Maps API加载完成后会调用全局的initGoogleMaps函数,所以我们需要在Reason里把这个函数挂载到window对象上,同时绑定Google Maps的核心API:
第一步:先定义Google Maps的类型和基础绑定
先通过BuckleScript的外部绑定语法,把Google Maps的核心类型和构造函数映射到Reason中:
// 定义地图配置项的类型 type mapOptions = { center: {lat: float, lng: float}, zoom: int, }; // 抽象地图实例的类型(不需要具体实现,只用来做类型约束) type map; // 绑定Google Maps的Map构造函数:对应原生JS的new google.maps.Map(element, options) [@bs.val] [@bs.scope ("google", "maps")] external createMap: (Dom.element, mapOptions) => map = "Map";
第二步:实现回调函数并挂载到全局
接下来编写初始化逻辑,然后把函数挂载到window上:
// 绑定全局window对象 [@bs.val] external window: Js.t({..}) = "window"; // 定义Google Maps加载完成后的回调函数 let initGoogleMaps = () => { // 获取页面上的地图容器(假设页面有id为"map"的元素) switch (Dom.document##getElementById("map")) { | Some(mapElement) => // 配置地图参数 let mapConfig = { center: {lat: -34.397, lng: 150.644}, zoom: 8, }; // 创建地图实例 let _mapInstance = createMap(mapElement, mapConfig); | None => Js.log("Error: 找不到id为map的容器元素") }; }; // 将回调函数挂载到window全局对象,供Google Maps API调用 window##initGoogleMaps = initGoogleMaps;
3. 扩展更多Google Maps API绑定
如果需要使用标记、信息窗口等其他API,只需要按照同样的方式添加外部绑定即可。比如添加Marker的绑定:
// 定义标记配置项类型 type markerOptions = { position: {lat: float, lng: float}, map: map, title: string, }; // 抽象标记实例类型 type marker; // 绑定Marker构造函数:对应原生JS的new google.maps.Marker(options) [@bs.val] [@bs.scope ("google", "maps")] external createMarker: (markerOptions) => marker = "Marker"; // 然后在initGoogleMaps中添加标记 let initGoogleMaps = () => { switch (Dom.document##getElementById("map")) { | Some(mapElement) => let mapConfig = {center: {lat: -34.397, lng: 150.644}, zoom: 8}; let mapInstance = createMap(mapElement, mapConfig); // 创建标记 let markerConfig = { position: {lat: -34.397, lng: 150.644}, map: mapInstance, title: "Hello from Reason!", }; let _marker = createMarker(markerConfig); | None => Js.log("Error: 找不到id为map的容器元素") }; };
关键注意点
- 这种绑定方式完全遵循原生JS的加载逻辑,API加载完成后会自动触发我们定义的回调,和原生写法的执行顺序、效果完全一致。
- BuckleScript默认会把代码包裹在模块作用域内,所以必须通过
window##initGoogleMaps = initGoogleMaps显式把回调函数暴露到全局,否则Google Maps API找不到这个函数。
内容的提问来源于stack exchange,提问作者Mateus Felipe
相关产品推荐
相关产品推荐

