javascript 调试Dash客户端回调

waxmsbnn  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(102)

我有以下的达世币应用程序(简化)。它显示文本框和单词列表(按钮)。单击具有文本的按钮,将相应的文本添加到文本框中(这是我希望客户端回调的部分)。还有另一个具有相同输出的回调(现在Dash 2.9允许这样做),当用户单击刷新术语的“-〉”按钮时会触发。

# Font Survey app
import re

import dash
import dash_bootstrap_components as dbc
import pandas as pd
from dash import dcc, html
from dash.dependencies import ALL, Input, Output, State
from dash.exceptions import PreventUpdate

EMPTY_DIV = html.Div()

# Div for sample list of terms
WORDS = list(pd.read_csv('font_terms.csv')['adj'])
word_items = [html.Li(children=dbc.Button(word, id={'type': 'fill-word-button', 'index': i})) for i, word in enumerate(WORDS)]
terms_div = html.Div(id='terms', children=word_items)

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP], prevent_initial_callbacks="initial_duplicate")
server =  app.server

app.layout = html.Div([
    dcc.Store(id='terms-store', data=WORDS),
    html.Div(id="adj-inputs", className="column",
            children= [dcc.Input(id={"type": "adj-input", "index": i}, value='') for i in range(5)]),
    terms_div,
    html.Button("→", id='forward-button', n_clicks=0),])

@app.callback(
    [Output({"type": "adj-input", "index": i}, 'value') for i in range(5)],
    Input({"type": "fill-word-button", "index": ALL}, "n_clicks"),
    State({'type': 'adj-input', 'index': ALL}, "value")

)
def fill_word_button(button_click, adj_inputs):
    ctx = dash.callback_context
    if not ctx.triggered:
        raise PreventUpdate
    button_id = ctx.triggered[0]['prop_id'].split('.')[0]

    button_index = int(re.search(r"\d+", button_id).group())
    # check if there is an empty text box
    if '' not in adj_inputs:
        raise PreventUpdate
    adj_inputs = ['' if a is None else a for a in adj_inputs] + [WORDS[button_index]]
    adj_inputs = list(set([a for a in adj_inputs if a!=''])) + [a for a in adj_inputs if a=='']
    return adj_inputs[:5]

# The following callback, once debugged, should replace the callback above ("fill_word_button")
# @app.clientside_callback(
#     """
#     function(n_clicks, adj_inputs, words) {
#         const ctx = dash_clientside.callbackContext;
#         if (!ctx.triggered.length) {
#             return adj_inputs;
#         }
#         const button_id = ctx.triggered[0]['prop_id'].split('.')[0];
#         const button_index = parseInt(button_id.match(/\d+/)[0]);
#         // check if there is an empty text box
#         if (adj_inputs.every(a => a !== '')) {
#             return adj_inputs;
#         }
#         adj_inputs = adj_inputs.concat([words[button_index]]);
#         adj_inputs = [...new Set(adj_inputs.filter(a => a !== '')), ...adj_inputs.filter(a => a === '')];
#         return adj_inputs.slice(0, 5);
#     }
#     """,
#     Output({"type": "adj-input", "index": ALL}, 'value'),
#     Input({"type": "fill-word-button", "index": ALL}, "n_clicks"),
#     State({'type': 'adj-input', 'index': ALL}, "value"),
#     State('terms-store', 'data')
# )

@app.callback(

    [Output({"type": "adj-input", "index": i}, 'value', allow_duplicate=True) for i in range(5)],
    [Input("forward-button", "n_clicks")],
    [State({'type': 'adj-input', 'index': ALL}, "value")],
)
def refresh_terms(forward_clicks, adj_inputs):
    ctx = dash.callback_context
    if not ctx.triggered:
        raise PreventUpdate
    button_id = ctx.triggered[0]['prop_id'].split('.')[0]

    if button_id == "forward-button":
        adj_inputs = [adj for adj in adj_inputs if adj !=""]
        # Do something with the adj_inputs e.g. upload to database and
        # db.insert_response_mysql(adj_inputs)
        # Reset adj_inputs
        return [""]*5

if __name__ == "__main__":
    app.run_server(debug=True, port=8000, host="0.0.0.0")

我遇到的错误与refresh_terms回调有关

[State({'type': 'adj-input', 'index': ALL}, "value")],
TypeError: 'NoneType' object is not callable

只有当我尝试使用客户端回调时才会发生这种情况,但当我使用单独的回调时就可以了。请帮助我调试此错误。

7jmck4yq

7jmck4yq1#

这是因为app.clientside_callback不是一个装饰器,而是一个常规函数,你只需要删除它前面的@
此外,回调上下文属性不是驼峰式的,即。

ctx = dash_clientside.callback_context;

(edit距离:3个字符;)

相关问题