在多选项卡破折号应用程序中将回调分配给组件的问题

issues with assigning callback to component in multi-tab dash application

我正在使用 Dash(来自 plotly 的 python 网络平台)构建一个多标签网络应用程序。 按照 https://dash.plot.ly/dash-core-components/tabs 的说明,我将选项卡内容呈现为回调,这是该说明中的首选方法。

现在在其中一个选项卡中,我需要创建两个下拉菜单,第二个下拉菜单依赖于第一个下拉菜单。我需要使用另一个回调函数来动态更新一个下拉列表以响应另一个下拉列表。

我的代码如下:

import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

myList = ['A', 'B']
myDict = {'A': [1,2,3],'B': [4,5,6] }

app.layout = html.Div([
    html.H1('Dash Tabs component demo'),
    dcc.Tabs(id="tabs-example", value='tab-1-example', children=[
        dcc.Tab(label='Tab One', value='tab-1-example'),
        dcc.Tab(label='Tab Two', value='tab-2-example'),
    ]),
    html.Div(id='tabs-content-example')
])


@app.callback(Output('tabs-content-example', 'children'),
              [Input('tabs-example', 'value')])
def render_content(tab):
    if tab == 'tab-1-example':
        return html.Div([
            html.H3('Tab content 1'),
            dcc.Dropdown( id='first-dropdown',
                          options=[{'label':l, 'value':l} for l in myList],
                          value = 'A'
                          ),
            dcc.Dropdown(id='second-dropdown',multi=True),  
        ])
    elif tab == 'tab-2-example':
        return html.Div([html.H3('Tab content 2')])

@app.callback(
    dash.dependencies.Output('first-dropdown', 'options'),
    [dash.dependencies.Input('second-dropdown', 'value')])
def update_dropdown(value):
    return [ {'label': i, 'value': i} for i in myDict[value] ]

if __name__ == '__main__':
    app.run_server(debug=True)

我收到错误消息:

dash.exceptions.NonExistentIdException:
                            Attempting to assign a callback to the
                            component with the id "first-dropdown" but no
                            components with id "first-dropdown" exist in the
                            app's layout.

我想是因为我的标签是回调生成的,我的第二次回调找不到标签中的组件。

有谁知道我怎样才能做到这一点? 非常感谢!

如果我理解正确的话,您只是想根据第一个下拉列表中的选择动态更改第二个下拉列表中的选项。您可以通过以下代码实现(Dash v1.6.0):

import dash
import dash_html_components as html
import dash_core_components as dcc

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

myList = ['A', 'B']
myDict = {'A': [1,2,3],'B': [4,5,6] }
default_category = 'A'
default_index = 0

tab1 = html.Div([
    html.H3('Tab content 1'),
    dcc.Dropdown(id='first-dropdown',
                 options=[{'label':l, 'value':l} for l in myList],
                 value = default_category
    ),
    dcc.Dropdown(id='second-dropdown',
                 options=[{'label':l, 'value':l} for l in myDict[default_category]],
                 value = myDict[default_category][default_index]
    )
])

tab2 = html.Div([
    html.H3('Tab content 2'),
])    

app.layout = html.Div([
    html.H1('Dash Tabs component demo'),
    dcc.Tabs(id="tabs-example", value='tab-1-example', children=[
        dcc.Tab(id="tab-1", label='Tab One', value='tab-1-example'),
        dcc.Tab(id="tab-2", label='Tab Two', value='tab-2-example'),
    ]),
    html.Div(id='tabs-content-example',
             children = tab1)
])

@app.callback(dash.dependencies.Output('tabs-content-example', 'children'),
             [dash.dependencies.Input('tabs-example', 'value')])
def render_content(tab):
    if tab == 'tab-1-example':
        return tab1
    elif tab == 'tab-2-example':
        return tab2

@app.callback(
    [dash.dependencies.Output('second-dropdown', 'options'),
     dash.dependencies.Output('second-dropdown', 'value')],
    [dash.dependencies.Input('first-dropdown', 'value')])
def update_dropdown(value):
    return [[ {'label': i, 'value': i} for i in myDict[value] ], myDict[value][default_index]]

if __name__ == '__main__':
    app.run_server(debug=True)