Я создал макет с вкладками для своего приложения Da sh:
import dash
import dash_table
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
TAB_LAYOUT = html.Div([
dcc.Tabs(id="tabs-main", value='tab-intro', children=[
dcc.Tab(label='Introduction', value='tab-intro'),
dcc.Tab(label='Your Files', value='tab-files'),
dcc.Tab(label='Basic', value='tab-basic'),
...
app.layout = html.Div([
TAB_LAYOUT,
...
# Top tabs callback
@app.callback(Output('tabs-content', 'children'),
[Input('tabs-main', 'value')])
def render_content(tab):
if tab == 'tab-intro':
return tab_intro_layout
elif tab == 'tab-basic':
return tab_basic_layout
elif tab == 'tab-files':
return tab_files_layout
...
Теперь на вкладке «файлы» у меня есть компонент загрузки файла и при успешной операции над файлом (добавление, удаление) У меня есть dbc.Toast
отчет о результате операции:
# files - update files table
@app.callback(
[
Output(component_id='upload-error-modal', component_property='style'),
Output(component_id='upload-error-message', component_property='children'),
Output(component_id='files-table', component_property='data'),
Output(component_id='toast-div', component_property='children'),
Output(component_id='upload-wait-div', component_property='children')
],
[
Input('session-id', 'children'),
Input('upload-data', 'contents'),
Input('upload-error-close-button', 'n_clicks'),
Input('files-table', 'data_previous')
],
[
State('upload-data', 'filename'),
State('files-table', 'data')
]
)
def update_files_table(session_id, upload_data_contents, error_close_button_nclicks,
data_previous, filename, data):
...
if removed_filename:
return {'display': 'none'}, '', data, make_toast_file_op(removed_filename, 'File removed.'), filename
def make_toast_file_op(filename, message):
return dbc.Toast([html.P(filename, className="mb-0")],
header=message,
className='toast',
headerClassName='toast-header',
bodyClassName='toast-body',
duration=3500)
Теперь при загрузке или удалении файла отображается Toast
, и он исчезает через 3,5 с.
Однако, если я переключаюсь на другую вкладку, скажем tab-basic
до того, как тост исчезает , создается впечатление, что обновляется неправильный компонент, и это приводит к ошибке:
An object was provided as `children` instead of a component, string, or number (or list of those). Check the children property that looks something like:
Пока я не переключаюсь на другую вкладку и не жду, пока исчезнет тост, ошибки нет.
Подробное сообщение об ошибке (ниже), похоже, указывает на то, что это действительно макет tab-basic
( когда я переключился на эту вкладку, чтобы получить ошибку), а не макет tab-files
.
Как я могу это исправить?
An object was provided as `children` instead of a component, string, or number (or list of those). Check the children property that looks something like:
{
"0": {
"props": {
"children": [
{
"props": {
"children": "Input Text"
},
"type": "H4",
"namespace": "dash_html_components"
},
{
"props": {
"id": "basic-input-box",
"style": {
"width": "100%",
"height": "400px"
},
"value": ""
},
"type": "Textarea",
"namespace": "dash_core_components"
},
{
"props": {
"children": [
{
"props": {
"children": [
{
"props": {
"children": [
{
"props": {
"children": "Example Text"
},
"type": "Label",
"namespace": "dash_html_components"
},
{
"props": {
"id": "basic-example-text",
"options": [
{
"label": "",
"value": "empty"
},
{
"label": "Example1",
"value": "ex1"
},
{
"label": "Example2",
"value": "ex2"
},
{
"label": "Example3",
"value": "ex3"
}
],
"value": "empty"
},
"type": "Dropdown",
"namespace": "dash_core_components"
}
],
"style": {
"width": "75%",
"border-bottom": "0px"
}
},
"type": "Td",
"namespace": "dash_html_components"
}
]
},
"type": "Tr",
"namespace": "dash_html_components"
}
],
"style": {
"width": "100%",
"border-bottom": "0px"
}
},
"type": "Table",
"namespace": "dash_html_components"
},
{
"props": {
"children": null
},
"type": "Br",
"namespace": "dash_html_components"
},
{
"props": {
"children": "Submit",
"id": "basic-button"
},
"type": "Button",
"namespace": "dash_html_components"
}
],
"style": {
"width": "48%",
"display": "inline-block"
}
},
"type": "Div",
"namespace": "dash_html_components"
},
"1": {
"props": {
"children": [
{
"props": {
"children": "Examples of fundamental capabilities"
},
"type": "H4",
"namespace": "dash_html_components"
},
{
"props": {
"children": "Example:",
"style": {
"color": "#eb7a34"
}
},
"type": "P",
"namespace": "dash_html_components"
},
{
"props": {
"children": null,
"id": "basic-example1"
},
"type": "Div",
"namespace": "dash_html_components"
},
{
"props": {
"children": null
},
"type": "Br",
"namespace": "dash_html_components"
},
{
"props": {
"children": "Example",
"style": {
"color": "#eb7a34"
}
},
"type": "P",
"namespace": "dash_html_components"
},
{
"props": {
"children": null,
"id": "basic-ex"
},
"type": "Div",
"namespace": "dash_html_components"
},
{
"props": {
"children": null
},
"type": "Br",
"namespace": "dash_html_components"
},
{
"props": {
"children": "Example",
"style": {
"color": "#eb7a34"
}
},
"type": "P",
"namespace": "dash_html_components"
},
{
"props": {
"children": null,
"id": "basic-1"
},
"type": "Div",
"namespace": "dash_html_components"
},
{
"props": {
"children": null
},
"type": "Br",
"namespace": "dash_html_components"
},
{
"props": {
"children": "Example:",
"style": {
"color": "#eb7a34"
}
},
"type": "P",
"namespace": "dash_html_components"
},
{
"props": {
"children": null,
"id": "basic-2"
},
"type": "Div",
"namespace": "dash_html_components"
}
],
"style": {
"width": "48%",
"display": "inline-block",
"float": "right"
}
},
"type": "Div",
"namespace": "dash_html_components"
},
"2": {
"props": {
"children": []
},
"type": "Div",
"namespace": "dash_html_components"
},
"props": {
"is_open": false,
"n_dismiss": null,
"n_dismiss_timestamp": 1584525204410
}
}