【问题标题】:How to get all selected values of dynamically selected dropdown in a single list?如何在单个列表中获取动态选择下拉列表的所有选定值?
【发布时间】:2020-03-09 16:18:35
【问题描述】:

如何在单个列表中获取动态选择的下拉列表的所有值? 我尝试使用 for 循环迭代在回调内部进行回调,但无法获得所需的列表。

def a_function 存在回调内部回调的问题。

如何获取动态更新的多个下拉列表的单个列表?

import dash
import dash_core_components as dcc
import dash_html_components as html

step = html.Div(
        children=[
            "Menu:",
            dcc.Dropdown(options=[{'label': v, 'value': v} for v in ['option1', 'option2', 'option3']])
        ])

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

div_list = [step]

app.layout = html.Div(
    children=[
        html.H1(children='Hello Dash'),
        html.Div(id='step_list', children=div_list),
        html.Div(id='local'),
        html.Button('Add Step', id='add_step_button', n_clicks_timestamp='0'),
        html.Button('Remove Step', id='remove_step_button', n_clicks_timestamp='0'),
        html.Div(id='tester_div'),
        html.Div(id='tester_div_2')])

@app.callback(
    [dash.dependencies.Output('step_list', 'children'),
    dash.dependencies.Output('local','value')],
    [dash.dependencies.Input('add_step_button', 'n_clicks_timestamp'),
    dash.dependencies.Input('add_step_button', 'n_clicks'),
     dash.dependencies.Input('remove_step_button', 'n_clicks_timestamp')],
    [dash.dependencies.State('step_list', 'children')])
def add_step(add_ts, clicks, remove_ts, div_list):
    add_ts = int(add_ts)
    remove_ts = int(remove_ts)
    if add_ts > 0 and add_ts > remove_ts and len(div_list) < 4:
        div_list += [html.Div(children=[
            "Menu:",
            dcc.Dropdown(id='dropdown_id_{}'.format(clicks), options=[{'label': v, 'value': v} for v in ['select1', 'select2', 'select3']])
        ])]
    if len(div_list) > 1 and remove_ts > add_ts:
        div_list = div_list[:-1]
    return div_list,len(div_list)


@app.callback(
    dash.dependencies.Output('tester_div', 'children'),
    [dash.dependencies.Input('local', 'value')])
def a_function(value):
    all_output = []
    if value:
        for i in range(1,value+1):
            @app.callback(dash.dependencies.Output('tester_div_2','children'),
                          [dash.dependencies.Input('dropdown_id_{}'.format(i), 'value')])
            def drop_output(valued):
                all_output.append(valued)
    return all_output

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

在这张图片中,输出应该是这样的列表:[option2, select1]

在这张图片中,输出应该是这样的列表:[option3, select3, select1, select2]

【问题讨论】:

    标签: python dynamic callback output plotly-dash


    【解决方案1】:

    Dash 不适用于其 ID 在初始构建布局时不存在的组件。像这样动态添加组件只有在页面第一次加载时这些组件已经存在的情况下才能工作,可能是您稍后显示的隐藏组件。据我所知,回调中的回调由于类似原因不起作用,但您可以在循环中创建回调。

    您需要重新设置布局设置,如果您需要更多帮助,可能会编辑您的帖子。

    编辑: 我认为pattern matching callbacks 可以做到这一点。在我最初回答的时候,我还没有和他们一起工作过(他们甚至可能还没有被释放),但现在我认为他们正是这个问题所要求的。在该页面上,有一个示例执行与您想要的非常相似的操作,添加任意数量的组件,并在回调中从每个组件中获取动态更新的值列表。

    【讨论】:

    • 但是我不知道我需要多少隐藏组件,因为我的数据集每次都在变化。
    • 让我们换个角度考虑一下。每个下拉组件需要做什么?也许有一种方法可以通过固定数量的下拉菜单或多下拉菜单来解决问题。
    • @chinni 我更新了我的答案。如果这仍然是您正在处理的问题,我认为现在有更好的方法。
    【解决方案2】:

    如果您在控件 ID 中有下拉菜单说“容器”,那么您可以使用以下几行代码轻松了解所选值:

    container_ext = [f for f in [container['props']['children'][i]['props'] for i in range(len(container['props']['children']))] if
                       'children' not in list(f.keys())]
    
    label = [p['id'] for p in container_ext ]
    values = [p['value'] for p in container_ext ]
    All_values = {}
    
    for i in range(len(label)):
        All_values[label[i]] = values[i]
    

    希望这可以从动态下拉列表中读取所有值

    【讨论】:

      【解决方案3】:

      我使用下面的 Derived from dash 示例在文本框中使用

      Pattern Matching Callbacks

      import dash
      import dash_core_components as dcc
      import dash_html_components as html
      from dash.dependencies import Input, Output, State, MATCH, ALL
      
      app = dash.Dash(__name__, suppress_callback_exceptions=True)
      
      app.layout = html.Div([
          html.Button("Add Filter", id="add-filter", n_clicks=0),#button
          html.Div(id='filter-container', children=[]),#filters
          html.Div(id='filter-container-output')#output of filters
      ])
      
      @app.callback(#add textboxes , index is taken as n_clicks 
          Output('filter-container', 'children'),
          Input('add-filter', 'n_clicks'),
          State('filter-container', 'children'))
      def display_textboxes(n_clicks, children):
          new_inbox = html.Div([
              html.Label('Text Input'), 
              dcc.Input(
                   id={
                  'type': 'dhiraj',
                  'index': n_clicks
                      },
                  value='MTL', 
                  type='text'
                  )
          ])
      
          children.append(new_inbox)
          return children
      
      @app.callback(#set outputs dynamic one is this 
          Output('filter-container-output', 'children'),
          Input({'type': 'dhiraj', 'index': ALL}, 'value')
      )
      def display_output(values):
          return html.Div([
              html.Div('Filter {} = {}'.format(i + 1, value))
              for (i, value) in enumerate(values)
          ])
      
      if __name__ == '__main__':
          app.run_server(debug=True)
      

      【讨论】:

        猜你喜欢
        • 2012-08-12
        • 2011-07-06
        • 2015-06-16
        • 2019-09-23
        • 1970-01-01
        • 1970-01-01
        • 2015-02-09
        • 1970-01-01
        • 2020-01-07
        相关资源
        最近更新 更多