简体   繁体   English

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

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

I'm building a multi-tab web application with Dash (a python web platform from plotly).我正在使用 Dash 构建一个多选项卡 web 应用程序(来自 plotly 的 python web 平台)。 following instruction from https://dash.plot.ly/dash-core-components/tabs I render tab content as callback, which is preferred method from this instruction.按照https://dash.plot.ly/dash-core-components/tabs的说明,我将选项卡内容呈现为回调,这是本说明中的首选方法。

Now in one of the tab, I need to create two dropdowns, the second dropdown is dependent on the first dropdown.现在在一个选项卡中,我需要创建两个下拉列表,第二个下拉列表取决于第一个下拉列表。 I need to use another callback function to dynamically update one dropdown in response to the other.我需要使用另一个回调 function 来动态更新一个下拉列表以响应另一个下拉列表。

My code is below:我的代码如下:

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)

I got error message:我收到错误消息:

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.

I think it's because my tabs are generated from callback, my second callback cannot find the component in the tab.我认为这是因为我的标签是从回调生成的,我的第二个回调在标签中找不到组件。

Does anyone know how I can achieve that?有谁知道我怎么能做到这一点? Thank you very much!非常感谢!

If I understand correctly you just want to dynamically change the options in the second dropdown based on selection in the first dropdown.如果我理解正确,您只想根据第一个下拉列表中的选择动态更改第二个下拉列表中的选项。 You can realize it with the following code (Dash v1.6.0):您可以使用以下代码(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)

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM