带有动态输入数的回调

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

我正在用行在 Dash 中创建一个组件。用户点击提交按钮后,应该创建一个多行图形(每行一行)。

这个行组件本来可以是一个表格组件,但由于我的组件在其中一列中包含按钮,所以我用 div 手动创建了它。原因是 Dash DataTable 不允许“HTML”组件。

重要的事情: 前两行包含默认值。此外,还有一个按钮可以创建一个新的空行,允许用户添加新信息。用户可以通过多次单击按钮来添加任意数量的行。

所有新的或编辑过的信息都必须保存在某个地方(状态),这样当用户点击提交按钮时,数字就会出现。

我仍然不确定这个逻辑是否适用于 Dash/Plotly。有什么想法吗?

附言我已经尝试过三行,但我必须在回调中对输入和输出进行硬编码。这不是合理的解决方案。

这里有一些示例代码无效。此外,一些函数将存储为单独的文件,因为它们描述了一些组件:

from dash import Dash, html, dcc, Input, Output

app = Dash(__name__, title="Dash App")


def input_container(index: int) -> dcc.Input:
    return dcc.Input(id={'type': 'my-input', 'index': index}, value='initial value')


# mutable state
state = [input_container(1)]


def inputs_container(state) -> html.Div:
    return html.Div(id='inputs-container', children=state)


def add_input_button(app, state) -> html.Button:
    @app.callback(Output('inputs-container', 'children'), Input('add-input', 'n_clicks'), prevent_initial_call=True)
    def add_input(n_clicks):
        return state.append(input_container(len(state) + 1))

    return html.Button('Add Input', id='add-input')


def submit_button(app, state) -> html.Button:
    @app.callback(Output('graph', 'figure'), Input('submit-input', 'n_clicks'))
    def submit_input(n_clicks):
        return '' # create some figure from the state values

    return html.Button('Submit Input', id='submit-input')


app.layout = html.Div([
    inputs_container(state),
    add_input_button(app, state),
    submit_button(app, state),
    dcc.Graph(id='graph'),
])

if __name__ == '__main__':
    app.run_server(debug=True)
python pandas callback plotly plotly-dash
1个回答
0
投票

看起来你已经接近

id={'type': 'my-input', 'index': index}
但你没有正确实现回调。

可以对

id
字段使用字典,然后在回调中使用
ALL
组件和
ctx.triggered_id[]
字典动态判断点击了哪个按钮。

为了清楚起见,这里有一个简化的例子:

from dash import Dash, ALL, ctx, dcc, html, Input, Output app = Dash(__name__) inputs = [ dcc.Input(id='output', type='text', size='100'), html.Br() ] for i in range(10): new_button = html.Button(f'click {i}', id={'type':'button', 'index':i, 'someattr':f'any data {i}'}) inputs.append(new_button) @app.callback( Output('output', 'value'), Input({'type':'button', 'index':ALL, 'someattr': ALL}, 'n_clicks') ) def update_output(n_clicks): if ctx.triggered_id is not None: index = ctx.triggered_id['index'] someattr = ctx.triggered_id['someattr'] return f'You clicked button #{index}, which had the attribute: "{someattr}".' else: return 'Click a button.' app.layout = html.Div(inputs) if __name__ == '__main__': app.run_server(debug=True)
一些重要的事情要记住:

    您可以向字典中添加任意数量的条目,将值传递给回调。
  • 您将收到
  • n_clicks
     参数的列表,而不是单个数字。例如,如果您单击第二个按钮,您将收到以下列表
    [0 1 0 0 0 0 0 0 0 0]
    .
  • 检查
  • None
     值可确保您的应用程序在未单击按钮的情况下触发回调时不会抛出回调异常。
© www.soinside.com 2019 - 2024. All rights reserved.