ひとりLiveView Advent Calendar の7日目の記事です
この記事はElixir Conf US 2021の発表したシステムの構築と関連技術の解説を目的とした記事です
GPS Loggerアプリから送信されたデータを表示するためにGoogleMapAPIを使用してLiveView上にGoogleMapを表示させます
今回は以下の3つを実装します
- npmでライブラリインストール
- JS HookでGoogleMapApiを読み込む
- LiveView上で表示
npm ライブラリの追加
phoenix 1.6になってからwebpackからesbuildに移行してnpm非依存になりましたが
npm installすれば普通に使用できます
assetsに移動してGoogleMap loaderを追加します
cd assets
npm install @googlemaps/js-api-loader
cd ..
#JS HookでGoogleMapの表示
LiveViewにはJS Hookというものがあって、
backendとfrontendでデータをやり取りする場合は APIを通すか、それ用のライブラリをインストールする必要があり、面倒くさいものですが
- JS側のhandleEvent, pushEvent
- Elixir側のpushEvent
という関数を使って相互に JSONとMapのやり取りができます
mount時にGoogleMapを表示するようにします
実際に試す場合は GoogleMapAPIのキーを取得してください
import { Loader } from "@googlemaps/js-api-loader";
let Hooks = {}
const apiKey = "your api key"
Hooks.Map = {
mounted() {
const loader = new Loader({
apiKey: apiKey,
version: "weekly",
})
loader.load().then(() => {
const map = new googlemaps.Map(
document.getElementById("map"),
{
center: { lat: 33.30639, lng: 130.41806 },
zoom: 9
}
);
window.map = map;
})
}
}
export default Hooks;
mount()関数が LiveView のmount後に実行されるので、
初期データの作成他に待ち受けるイベントを記述したりします
hooksファイルができたら,liveSocketのoptionsの箇所に hooks: Hooks
で追加します
...
import Hooks from "./hooks"
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}})
...
Hooksを読み込む際の注意点ですが
Hooksを読み込むタグにIDをつけて読み込むモジュールをphx-hook="Map"
で指定します
また、canvasなどタグ内が頻繁に変化する箇所はLiveViewが変更を検知して再レンダリングされるので、
LiveViewが変更しないようにphx-update="ignore"
を指定します
<h1>Show Map</h1>
<%= if @live_action in [:edit] do %>
<%= live_modal LiveLoggerWeb.MapLive.FormComponent,
id: @map.id,
title: @page_title,
action: @live_action,
map: @map,
return_to: Routes.map_show_path(@socket, :show, @map) %>
<% end %>
<ul>
<li>
<strong>Name:</strong>
<%= @map.name %>
</li>
<li>
<strong>Description:</strong>
<%= @map.description %>
</li>
</ul>
<!--- 以下追加 --->
<div id="googleMap" phx-update="ignore" phx-hook="Map">
<div id="map"></div>
</div>
<span><%= live_patch "Edit", to: Routes.map_show_path(@socket, :edit, @map), class: "button" %></span> |
<span><%= live_redirect "Back", to: Routes.map_index_path(@socket, :index) %></span>
google mapの表示領域の高さを600pxに指定します。
heightを指定しないとmapが表示されないので忘れないようにしましょう
...
#map{
height: 600px
}
GoogleMapが表示されました!
最後に
LiveView上にGoogleMapを表示することができました!
本記事は以上になります
次はBulmaを使用してスタイリングをしていきます
code