此 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
使用模式匹配回调可以解决这个问题。给你的动态组件字典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"
# }
# ],
# ...