浏览代码

frontend: refine `put_buttons` on-click event

wangweimin 4 年之前
父节点
当前提交
9e0b7089f0
共有 4 个文件被更改,包括 26 次插入25 次删除
  1. 2 2
      test/template.py
  2. 2 3
      webiojs/src/main.ts
  3. 8 20
      webiojs/src/models/output.ts
  4. 14 0
      webiojs/src/session.ts

+ 2 - 2
test/template.py

@@ -144,7 +144,7 @@ def basic_output():
         ], size=PopupSize.NORMAL)
         ], size=PopupSize.NORMAL)
 
 
     with use_scope('popup_btn'):
     with use_scope('popup_btn'):
-        put_buttons(['popup()'], onclick=[show_popup])
+        put_buttons([('popup()', '')], onclick=[show_popup])
 
 
     def edit_row(choice, row):
     def edit_row(choice, row):
         put_text("You click %s button at row %s" % (choice, row), scope='table_cell_buttons')
         put_text("You click %s button at row %s" % (choice, row), scope='table_cell_buttons')
@@ -755,7 +755,7 @@ def save_output(browser: Chrome, filename=None, process_func=None):
     """
     """
     raw_html = browser.find_element_by_id('markdown-body').get_attribute('innerHTML')
     raw_html = browser.find_element_by_id('markdown-body').get_attribute('innerHTML')
     html = re.sub(r'"pywebio-scope-.*?"', '', raw_html)
     html = re.sub(r'"pywebio-scope-.*?"', '', raw_html)
-    html = re.sub(r"WebIO.DisplayAreaButtonOnClick\(.*?\)", '', html)
+    html = re.sub(r"WebIO.pushData\(.*?\)", '', html)
     html = re.sub(r"</(.*?)>", r'</\g<1>>\n', html)  # 进行断行方便后续的diff判断
     html = re.sub(r"</(.*?)>", r'</\g<1>>\n', html)  # 进行断行方便后续的diff判断
     if process_func:
     if process_func:
         html = process_func(html)
         html = process_func(html)

+ 2 - 3
webiojs/src/main.ts

@@ -1,8 +1,7 @@
 import {config as appConfig, state} from "./state";
 import {config as appConfig, state} from "./state";
-import {ClientEvent, Command, HttpSession, is_http_backend, Session, WebSocketSession} from "./session";
+import {ClientEvent, Command, HttpSession, is_http_backend, pushData, Session, WebSocketSession} from "./session";
 import {InputHandler} from "./handlers/input"
 import {InputHandler} from "./handlers/input"
 import {OutputHandler} from "./handlers/output"
 import {OutputHandler} from "./handlers/output"
-import {DisplayAreaButtonOnClick} from "./models/output"
 import {CloseHandler, CommandDispatcher} from "./handlers/base"
 import {CloseHandler, CommandDispatcher} from "./handlers/base"
 import {PopupHandler} from "./handlers/popup";
 import {PopupHandler} from "./handlers/popup";
 import {openApp} from "./utils";
 import {openApp} from "./utils";
@@ -72,5 +71,5 @@ window.WebIO = {
         return state.CurrentSession.send_message(msg);
         return state.CurrentSession.send_message(msg);
     },
     },
     'openApp': openApp,
     'openApp': openApp,
-    'DisplayAreaButtonOnClick': DisplayAreaButtonOnClick,
+    'pushData': pushData,
 };
 };

+ 8 - 20
webiojs/src/models/output.ts

@@ -1,9 +1,8 @@
-import {state} from '../state'
 import {b64toBlob} from "../utils";
 import {b64toBlob} from "../utils";
 
 
 /*
 /*
 * 当前限制
 * 当前限制
-* 若外层为layout类的Widget,则内层Widget在get_element中绑定的事件将会失效
+* 若Widget被作为其他Widget的子项时,该Widget中绑定的事件将会失效
 * */
 * */
 
 
 export interface Widget {
 export interface Widget {
@@ -55,34 +54,23 @@ let Html = {
 let Buttons = {
 let Buttons = {
     handle_type: 'buttons',
     handle_type: 'buttons',
     get_element: function (spec: any) {
     get_element: function (spec: any) {
-        const btns_tpl = `<div>{{#buttons}}
-                             <button onclick="WebIO.DisplayAreaButtonOnClick(this, '{{callback_id}}')" class="btn {{#color}}btn-{{color}}{{/color}}{{#small}} btn-sm{{/small}}">{{label}}</button> 
+        const btns_tpl = `<div>{{#buttons}} 
+                                <button class="btn {{#color}}btn-{{color}}{{/color}}{{#small}} btn-sm{{/small}}">{{label}}</button> 
                           {{/buttons}}</div>`;
                           {{/buttons}}</div>`;
         spec.color = spec.link ? "link" : "primary";
         spec.color = spec.link ? "link" : "primary";
         let html = Mustache.render(btns_tpl, spec);
         let html = Mustache.render(btns_tpl, spec);
-        let elem =  $(html);
+        let elem = $(html);
 
 
         let btns = elem.find('button');
         let btns = elem.find('button');
-        for(let idx =0; idx< spec.buttons.length; idx++)
-            btns.eq(idx).val(JSON.stringify(spec.buttons[idx].value));
+        for (let idx = 0; idx < spec.buttons.length; idx++) {
+            // note: 若Buttons被作为其他Widget的子项时,Buttons中绑定的事件将会失效,所以使用onclick attr设置点击事件
+            btns.eq(idx).attr('onclick', `WebIO.pushData(${JSON.stringify(spec.buttons[idx].value)}, "${spec.callback_id}")`);
+        }
 
 
         return elem;
         return elem;
     }
     }
 };
 };
 
 
-// 显示区按钮点击回调函数
-export function DisplayAreaButtonOnClick(this_ele: HTMLElement, callback_id: string) {
-    if (state.CurrentSession === null)
-        return console.error("can't invoke DisplayAreaButtonOnClick when WebIOController is not instantiated");
-
-    let val = $(this_ele).val() as string;
-    state.CurrentSession.send_message({
-        event: "callback",
-        task_id: callback_id,
-        data: JSON.parse(val)
-    });
-}
-
 // 已废弃。为了向下兼容而保留
 // 已废弃。为了向下兼容而保留
 let File = {
 let File = {
     handle_type: 'file',
     handle_type: 'file',

+ 14 - 0
webiojs/src/session.ts

@@ -1,4 +1,5 @@
 import {error_alert} from "./utils";
 import {error_alert} from "./utils";
+import {state} from "./state";
 
 
 export interface Command {
 export interface Command {
     command: string
     command: string
@@ -257,4 +258,17 @@ export function is_http_backend(backend_addr: string) {
             resolve(false);
             resolve(false);
         });
         });
     });
     });
+}
+
+
+// 向服务端发送数据
+export function pushData(data: any, callback_id: string) {
+    if (state.CurrentSession === null)
+        return console.error("can't invoke PushData when WebIOController is not instantiated");
+
+    state.CurrentSession.send_message({
+        event: "callback",
+        task_id: callback_id,
+        data: data
+    });
 }
 }