Sfoglia il codice sorgente

Dynamically load js components.

Dominique CLAUSE 2 anni fa
parent
commit
d82e4c8582
2 ha cambiato i file con 27 aggiunte e 2 eliminazioni
  1. 7 0
      nicegui/outbox.py
  2. 20 2
      nicegui/templates/index.html

+ 7 - 0
nicegui/outbox.py

@@ -33,6 +33,13 @@ async def loop() -> None:
         try:
         try:
             for client_id, elements in update_queue.items():
             for client_id, elements in update_queue.items():
                 elements = {element_id: element._to_dict() for element_id, element in elements.items()}
                 elements = {element_id: element._to_dict() for element_id, element in elements.items()}
+                loading = {
+                    'c': []     # vue components
+                }
+                for element_id, element in elements.items():
+                    for component in element['components']:
+                        loading['c'].append(component)
+                # coros.append(globals.sio.emit('loading', loading, room=client_id))
                 coros.append(globals.sio.emit('update', elements, room=client_id))
                 coros.append(globals.sio.emit('update', elements, room=client_id))
             update_queue.clear()
             update_queue.clear()
             for client_id, message_type, data in message_queue:
             for client_id, message_type, data in message_queue:

+ 20 - 2
nicegui/templates/index.html

@@ -33,6 +33,7 @@
       const True = true;
       const True = true;
       const False = false;
       const False = false;
       const None = undefined;
       const None = undefined;
+      const loaded = [];
 
 
       const elements = {{ elements | safe }};
       const elements = {{ elements | safe }};
 
 
@@ -70,6 +71,11 @@
       }
       }
       function renderRecursively(elements, id) {
       function renderRecursively(elements, id) {
         const element = elements[id];
         const element = elements[id];
+
+        for (const component of element['components']) {
+          loaded.push(component);
+        }
+
         const props = {
         const props = {
           id: element.id,
           id: element.id,
           ref: 'r' + element.id,
           ref: 'r' + element.id,
@@ -147,7 +153,7 @@
         document.body.removeChild(anchor);
         document.body.removeChild(anchor);
       }
       }
 
 
-      const app = Vue.createApp({
+      let app = Vue.createApp({
         data() {
         data() {
           return {
           return {
             elements,
             elements,
@@ -175,7 +181,19 @@
           window.socket.on("disconnect", () => {
           window.socket.on("disconnect", () => {
             document.getElementById('popup').style.opacity = 1;
             document.getElementById('popup').style.opacity = 1;
           });
           });
-          window.socket.on("update", (msg) => Object.entries(msg).forEach(([id, el]) => this.elements[el.id] = el));
+          window.socket.on("update", async (msg) => {
+            for (const [id, element] of Object.entries(msg)) {
+              for (const component of element['components']) {
+                if (!loaded.includes(component)) {
+                  console.log('TRY TO LOAD COMPONENT', component);
+                  const { default: vue_component } = await import(`{{ prefix | safe }}/_nicegui/0.1.0/components/${component}`);
+                  app = app.component(component.replace('vue_', ''), vue_component);
+                  loaded.push(component);
+                }
+              }
+              this.elements[element.id] = element;
+            }
+          });
           window.socket.on("run_method", (msg) => getElement(msg.id)?.[msg.name](...msg.args));
           window.socket.on("run_method", (msg) => getElement(msg.id)?.[msg.name](...msg.args));
           window.socket.on("run_javascript", (msg) => runJavascript(msg['code'], msg['request_id']));
           window.socket.on("run_javascript", (msg) => runJavascript(msg['code'], msg['request_id']));
           window.socket.on("open", (msg) => (location.href = msg.startsWith('/') ? "{{ prefix | safe }}" + msg : msg));
           window.socket.on("open", (msg) => (location.href = msg.startsWith('/') ? "{{ prefix | safe }}" + msg : msg));