我有以下Dash应用程序(简化).它显示文本框和单词列表(按钮).您可以单击包含文本的按钮将相应的文本添加到文本框中(这是我想要客户端回调的部分).还有另一个具有相同输出的回调(现在允许使用Dash2.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

这只在我try 使用客户端回调时才会发生,但当我使用单独的回调时就可以了.请帮我调试这个错误.

推荐答案

这是因为app.clientside_callback不是一个装饰符,而是一个常规函数,您只需要删除它前面的@即可.

此外,回调上下文属性也不是驼峰式的,即.

ctx = dash_clientside.callback_context;

(编辑距离:3位字符;)

Javascript相关问答推荐

错误:(0,react__WEBPACK_IMPORTED_MODULE_1__.useSYS State)不是函数或其返回值不可迭代

如何制作删除按钮以从列表中删除该项目所属的项目?

如何比较嵌套对象的更改并创建更改报告

Fastify错误:CORS策略已阻止从起源api-dev.example.com上的MLhttp请求

如何让\w token 在此RegEx中表现得不贪婪?

不渲染具有HTML参数的React元素

如何编辑代码FlipDown.js倒计时?

React:未调用useState变量在调试器的事件处理程序中不可用

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

将现场录音发送到后端

从Node JS将对象数组中的数据插入Postgres表

使用Java脚本根据按下的按钮更改S文本

JS—删除对象数组中对象的子对象

保持物品顺序的可变大小物品分配到平衡组的算法

为什么这个.add.group({})在教程中运行得很好,但在我的游戏中就不行了?

创建以键值对为有效负载的Redux Reducer时,基于键的类型检测

为什么JPG图像不能在VITE中导入以进行react ?

以编程方式聚焦的链接将被聚焦,但样式不适用

第一项杀死下一项,直到数组长度在javascript中等于1

WebSocketException:远程方在未完成关闭握手的情况下关闭了WebSocket连接.&#三十九岁;