Dash Python 中的动态输入

问题描述 投票:0回答:1

此 Dash 回调从 JSON 文件读取组件 ID 作为输入组件。当列表是静态时,回调本身工作正常,但如果将 id 添加到列表或从列表中删除,则应用程序会崩溃并给出“缺少输入组件”错误。 JSON 文件正在按预期更新,但输入组件没有根据 JSON 更改重新定义。我该如何解决这个问题?

@dash.callback(
    Output('selectedPatientsStoreBeta1', 'data'),
    [Input(value, 'value') for value in safetyCheckInfoReadout()[1]],
    prevent_initial_call=True,
)
def patientSelection(*args):
    selectionValues = []
    for i in args:
        if str(i) == 'None' or i is None:
            iVal = ''
        else:
            iVal = str(i).translate(str.maketrans('', '', '"\'[]'))
        selectionValues.append(iVal)

    selectedPatients = []
    for index, value in enumerate(safetyCheckInfoReadout()[1]):
        if str(value.split('-')[-1]) in selectionValues[index]:
            selectedPatients.append(str(value.split('-')[-1]))
    if len(selectedPatients) > 0:
        selectedPatients = str(selectedPatients).translate(
            str.maketrans('', '', '"\' []'))
    else:
        selectedPatients = ''

    return selectedPatients
python json input callback plotly-dash
1个回答
0
投票

TL;博士

使用模式匹配回调可以解决这个问题。给你的动态组件字典ID:

...
dcc.Input(id={'type': 'my_form_field', index: 1}),
dcc.Input(id={'type': 'my_form_field', index: 2}),
...

一次性处理它们的所有值:

from dash import ALL

@dash.callback(
    Output('some_output_component_id', 'data'),
    Input({'type': 'my_form_field', 'index': ALL}, 'value'),
    prevent_initial_call=True)
def on_my_form_field_change(values: list):
    for value in values:
        ...

并非所有组件都支持此功能!例如,

dcc.Input
(来自 dash 核心组件)可以,但
dbc.Input
(来自 dash bootstrap 组件)则不能。

注释

还值得注意的是,按显示方式传递输入将无法按预期工作。是的,可以将装饰器的参数绑定到可调用结果。但是,在这种情况下,传递的是列表理解的结果,一旦计算就永远不会再改变。此外,

Dash
实际上解析callback
装饰器的参数
,并填充
callback_map
以及一些其他属性。所以这不是更改回调签名的方法。举例说明:

app.layout = html.Div([
    dcc.Store(id='test0', data='test0'),
    dcc.Store(id='test1', data='test1'),
    dbc.Button('Click!', id='button', n_clicks=0),
    dbc.Input(id='output')])

def get_state(tick: int = 0):
    # switches between test0 and test1
    return State(f'test{tick % 2}', 'data')

# initialize with test1
state = get_state(-1)

@dash.callback(
    Output('output', 'value'),
    Input('button', 'n_clicks'),
    state)
def testing(clicks, value):
    global state
    print(f"clicks={clicks}, argument={value}, variable={state.component_id}")
    state = get_state(clicks)
    return value

单击时的示例输出:

clicks=0, argument=test1, variable=test1
clicks=1, argument=test1, variable=test0
clicks=2, argument=test1, variable=test1
clicks=3, argument=test1, variable=test0

使用的状态保持不变:

print(app.callback_map['output.value'])
# ...
# {
#   "state": [
#    {
#      "id": "test1",
#      "property": "data"
#    }
#  ],
# ...

© www.soinside.com 2019 - 2024. All rights reserved.