如何在Plotly Dash中动态地实现ListGroupItem的ListGroup?

问题描述

我想创建一个单词列表,这些单词在Dash应用程序中动态更新。 为此,我想使用dash_bootstrap_components库中的ListGroup和ListGroupItem。

现在,如果ListGroup组件的children属性在输入和输出上具有相同的类型,则我的回调函数将起作用。但是,即使我的输出是列表(显然是ListGroup的子级可以接受的类型),我从函数中读取的也是字典。类型:{'props':{'children':'sample_word'},'type':'ListGroupItem','namespace':'dash_bootstrap_components'}。

然后的问题是,如何从ListGroup组件中获取要在回调中返回的ListGroupItem组件的列表?

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html

app.layout = html.Div(children=[dbc.Row(dbc.ListGroup(id='list-group-items'))])

@app.callback([Output('list-group-items','children')],[Input('input-domain-specific-words','value'),Input('add-button','n_clicks'),Input('delete-button',Input('reset-button','n_clicks')],[State('list-group-items','children')])

def update_list(word,n_clicks_add,n_clicks_delete,n_clicks_reset,listChildren):
    ctx = dash.callback_context
    if not ctx.triggered:
        raise dash.exceptions.PreventUpdate
    else:
        button_id = ctx.triggered[0]['prop_id'].split('.')[0]

    if button_id not in ['add-button','delete-button','reset_button']:
        raise dash.exceptions.PreventUpdate
    else:
        
        if button_id == 'delete-button':
            for item in listChildren:
                if item.children == word:
                    listChildren.remove(item)
                
        elif button_id == 'add-button':
            listChildren.append(dbc.ListGroupItem(word))

        elif button_id == 'reset-button':
            listChildren = []
    return [listChildren]

解决方法

我希望这以后可能会有用,即使仅对我自己也是如此。答案是ListGroup组件会返回一个ListGroupItem组件列表,这些列表在回调中收集时以JSON编写。因此,每当将ListGroupItem组件追加到ListGroup时,它将作为ListGroupItem()元素添加,但是,当您将其取回时,它将像JSON一样读取。在下面,我从代码中显示一个示例:string1和string2先前已添加到ListGroup组件中,但是string3已添加到当前回调中,因此它显示为ListGroupItem元素而不是JSON。

[{'props': {'children': 'string1'},'type': 'ListGroupItem','namespace': 'dash_bootstrap_components'},{'props': {'children': 'string2'},ListGroupItem('string3')]

我的特定回调的最终版本是:

@app.callback(
    [Output('list-group-items','children')],[Input('input-domain-specific-words','value'),Input('add-button','n_clicks'),Input('delete-button',Input('reset-button','n_clicks')],[State('list-group-items',)

def updateWordList(word,n_clicks_add,n_clicks_delete,n_clicks_reset,listChildren):

    ctx = dash.callback_context
    if not ctx.triggered:
        raise dash.exceptions.PreventUpdate
    else:
        button_id = ctx.triggered[0]['prop_id'].split('.')[0]

    if button_id not in ['add-button','delete-button','reset-button']:
        raise dash.exceptions.PreventUpdate
    else:
        if not listChildren:
            listChildren = []

        if button_id == 'delete-button':
            for item in listChildren:
                if item['props']['children'] == word:
                    listChildren.remove(item)
                
        elif button_id == 'add-button':
            listChildren.append(dbc.ListGroupItem(word))

        elif button_id == 'reset-button':
            print('pressed reset')
            return [[]]
    
    return [listChildren]