Преглед изворни кода

move leaflet code into custom Vue component

Falko Schindler пре 2 година
родитељ
комит
c1fd9b03b8
3 измењених фајлова са 40 додато и 71 уклоњено
  1. 18 0
      examples/map/leaflet.js
  2. 10 53
      examples/map/leaflet.py
  3. 12 18
      examples/map/main.py

+ 18 - 0
examples/map/leaflet.js

@@ -0,0 +1,18 @@
+export default {
+  template: "<div></div>",
+  mounted() {
+    this.map = L.map(this.$el);
+    L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png").addTo(this.map);
+  },
+  methods: {
+    set_location(latitude, longitude) {
+      this.target = L.latLng(latitude, longitude);
+      this.map.setView(this.target, 9);
+      if (this.marker) {
+        this.map.removeLayer(this.marker);
+      }
+      this.marker = L.marker(this.target);
+      this.marker.addTo(this.map);
+    },
+  },
+};

+ 10 - 53
examples/map/leaflet.py

@@ -1,61 +1,18 @@
-import logging
 from typing import Tuple
 
 from nicegui import ui
+from nicegui.element import Element
+from nicegui.vue import register_component
 
+register_component('leaflet', __file__, 'leaflet.js')
 
-class map(ui.card):
 
-    def __init__(self) -> None:
-        super().__init__()
-        self.classes('osm-map').style('width:100%;height:300px')
-        self.add_leaflet_js()
-
-    async def set_location(self, location: Tuple[float, float]) -> None:
-        print(location, flush=True)
-        try:
-            await ui.run_javascript(f'''
-                window.target = L.latLng("{location[0]}", "{location[1]}");
-                window.map.setView(target, 9);
-                if (window.marker != undefined) window.map.removeLayer(window.marker);
-                window.marker = L.marker(target);
-                window.marker.addTo(window.map);
-            ''', respond=False)
-        except:
-            logging.exception(f'could not update {location}')
+class leaflet(Element):
 
-    @staticmethod
-    def add_leaflet_js():
-        ui.add_head_html(r'''
-        <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
-        <link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>
-        <script>
-            function waitForElm(selector) {
-                return new Promise(resolve => {
-                    if (document.querySelector(selector)) {
-                        return resolve(document.querySelector(selector));
-                    }
-
-                    const observer = new MutationObserver(mutations => {
-                        if (document.querySelector(selector)) {
-                            resolve(document.querySelector(selector));
-                            observer.disconnect();
-                        }
-                    });
+    def __init__(self) -> None:
+        super().__init__('leaflet')
+        ui.add_head_html('<link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>')
+        ui.add_head_html('<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>')
 
-                    observer.observe(document.body, {
-                        childList: true,
-                        subtree: true,
-                    });
-                });
-            }
-            document.addEventListener("DOMContentLoaded", function() {
-                waitForElm('.osm-map').then((container) => {
-                    window.map = L.map(container);
-                    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
-                        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
-                    }).addTo(window.map);
-                });
-            });
-        </script>
-        ''')
+    def set_location(self, location: Tuple[float, float]) -> None:
+        self.run_method('set_location', location[0], location[1])

+ 12 - 18
examples/map/main.py

@@ -1,28 +1,22 @@
 #!/usr/bin/env python3
-import leaflet  # this module wraps the JavaScript lib leafletjs.com into an easy-to-use NiceGUI element
+from leaflet import leaflet  # this module wraps the JavaScript lib leafletjs.com into an easy-to-use NiceGUI element
 
 from nicegui import Client, ui
-from nicegui.events import ValueChangeEventArguments
+
+locations = {
+    (52.5200, 13.4049): 'Berlin',
+    (40.7306, -74.0060): 'New York',
+    (39.9042, 116.4074): 'Beijing',
+    (35.6895, 139.6917): 'Tokyo',
+}
 
 
 @ui.page('/')
 async def main_page(client: Client):
-    map = leaflet.map()
-    locations = {
-        (52.5200, 13.4049): 'Berlin',
-        (40.7306, -74.0060): 'New York',
-        (39.9042, 116.4074): 'Beijing',
-        (35.6895, 139.6917): 'Tokyo',
-    }
-
-    async def handle_location_change(e: ValueChangeEventArguments) -> None:
-        with e.client:
-            await map.set_location(e.value)
-    selection = ui.select(locations, on_change=handle_location_change).style('width: 10em')
-    await client.handshake()  # all code below is executed after client is connected
-    default_location = next(iter(locations))
-    # this will trigger the map.set_location event; which is js and must be run after client has connected
-    selection.set_value(default_location)
+    map = leaflet().classes('w-full h-96')
+    selection = ui.select(locations, on_change=lambda e: map.set_location(e.value)).classes('w-40')
+    await client.handshake()  # wait for websocket connection
+    selection.set_value(next(iter(locations)))  # trigger map.set_location with first location in selection
 
 
 ui.run()