首页 > 解决方案 > 无法在 div 子组件中追加

问题描述

我有多个相互依赖的下拉列表。它们将具有相同的值列表。但是,如果我从下拉列表中的任何一个中选择值,那么其他下拉列表将无法采用该值。所以这部分是有效的。

我印象深刻的部分是:

我有三个下拉菜单。如果我从第一个下拉列表中选择,那么它将为每个选定的值附加一个范围滑块。

如果来自第二个下拉列表,那么它将为每个选定的值附加一个日期选择器,第三个下拉列表将用于文本框。

这部分children.append(slider_comp)给了我错误

Callback error updating {"index":"num","type":"dynamic-output"}.children
Traceback (most recent call last):
  File "/media/kriti/Data_Drive/flask_app/flask_page/annot_app/t4.py", line 136, in display_output
    children.append(slider_comp)
AttributeError: 'str' object has no attribute 'append'

我知道这个值是 none 这就是它给出错误的原因但是如何解决它?

代码:

# -*- coding: utf-8 -*-
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ALL, MATCH

app = dash.Dash(__name__)

# all_options = {
#     'America': ['New York City', 'San Francisco', 'Cincinnati'],
#     'Canada': [u'Montréal', 'Toronto', 'Ottawa']
# }

all_options = [i for i in range(10)]
app.layout = html.Div([



    dcc.Dropdown(
        id={'type':'dropdown', 'index':'num'},
        options=[{'label': k, 'value': k} for k in all_options],
        value=[],
        multi=True
    ),

    html.Div(
    id={
        'type': 'dynamic-output',
        'index': 'num'
        },
    children =['a']
    ),
    html.Hr(),

    dcc.Dropdown(
        id={'type':'dropdown', 'index':'date'},
        options=[{'label': k, 'value': k} for k in all_options],
        value=[],
        multi=True
    ),

    html.Div(
    id={
        'type': 'dynamic-output',
        'index': 'date'
        },
    children =['b']
    ),
    html.Hr(),

    dcc.Dropdown(
        id={'type':'dropdown', 'index':'text'},
        options=[{'label': k, 'value': k} for k in all_options],
        value=[],
        multi=True
    ),


    html.Div(
    id={
        'type': 'dynamic-output',
        'index': 'text'
        },
    children =['c']
    ),

    html.Div(id='display-selected-values')
])




# def set_options(values1, values2):
#     print(values1, values2)


# col = ['date', 'num', 'text']
# for i in range(3):
#     app.callback(
#         dash.dependencies.Output(f'{col[i%3]}-dropdown', 'options'),
#         [dash.dependencies.Input(f'{col[(i+1)%3]}-dropdown', 'value'), dash.dependencies.Input(f'{col[(i+2)%3]}-dropdown', 'value')])(set_options)




@app.callback(
    dash.dependencies.Output({'type':'dropdown', 'index':'date'}, 'options'),
    [dash.dependencies.Input({'type':'dropdown', 'index':'num'}, 'value'), dash.dependencies.Input({'type':'dropdown', 'index':'text'}, 'value')])
def set_date_options(values_num, values_text):
    values = values_num + values_text
    return [{'label': i, 'value': i} for i in [e for e in all_options if e not in values]]


@app.callback(
    dash.dependencies.Output({'type':'dropdown', 'index':'num'}, 'options'),
    [dash.dependencies.Input({'type':'dropdown', 'index':'date'}, 'value'), dash.dependencies.Input({'type':'dropdown', 'index':'text'}, 'value')])
def set_num_options(values_date, values_text):
    values = values_date + values_text
    return [{'label': i, 'value': i} for i in [e for e in all_options if e not in values]]


@app.callback(
    dash.dependencies.Output({'type':'dropdown', 'index':'text'}, 'options'),
    [dash.dependencies.Input({'type':'dropdown', 'index':'num'}, 'value'), dash.dependencies.Input({'type':'dropdown', 'index':'date'}, 'value')])
def set_num_options(values_num, values_date):
    values = values_num + values_date
    return [{'label': i, 'value': i} for i in [e for e in all_options if e not in values]]



@app.callback(
    dash.dependencies.Output('display-selected-values', 'children'),
    [dash.dependencies.Input({'type':'dropdown', 'index':'num'}, 'value'),
     dash.dependencies.Input({'type':'dropdown', 'index':'date'}, 'value'),
     dash.dependencies.Input({'type':'dropdown', 'index':'text'}, 'value')])
def set_display_children(value_num, value_date, value_text):
    return u'{} is a city in {} {}'.format(
        value_num, value_date, value_text,
    )


@app.callback(
    Output({'type': 'dynamic-output', 'index': MATCH}, 'children'),
    [Input({'type':'dropdown', 'index':MATCH}, 'value')],
    [State({'type': 'dynamic-output', 'index': MATCH}, 'children')]
)
def display_output(a, children):
    if a:
        print("-->",children)
        slider_comp = html.Div(children=dcc.RangeSlider(id=f'num_filter',
                                          updatemode='drag', \
                                          min=(1), max=(10), \
                                          value=[(1), (10)], step=1)
        )
        children.append(slider_comp)
        return children
    return ""


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

在此处输入图像描述

编辑:其中一个技巧是添加:

if children=="":
    children = []

这将适用于我的情况,但我不明白为什么当我在其中设置一些值时孩子们没有显示任何['a']内容。

标签: plotlyplotly-dash

解决方案


看看你的错误:

AttributeError: 'str' object has no attribute 'append'

这并不是说您的对象是 None,而是说它是 str 并且字符串没有附加功能。Strings并且None是两种不同的类型!

现在,您遇到的根本问题是您dynamic-output在函数的最后一行将您设置为字符串值:

def display_output(a, children):
    if a:
        (...)
        return children
    return ""

如果你返回一个列表而不是 "" 你应该没问题。


推荐阅读