Dash 多页“存储组件”值

问题描述 投票:0回答:0

我正在尝试实现一个多页面 Dash webapp,但在跨页面来回切换时,我很难“存储”组件中的更改。即,每次我移动到新页面时,布局都会刷新。

下面有一个(最小的?)代码示例用于重现性目的,其中第 1 页有一个 html 表,第一行允许用户输入和添加按钮,然后也可以删除插入的行。 第 2 页只是一个来回切换的占位符。

我想一种策略可能是拥有不同的

dcc.Store
并记录发生的事情,并在切换时从中填充页面。但我希望有更好的策略 tbh :)

index.py

import dash
from dash import html, dcc
import dash_bootstrap_components as dbc

# Dash app
app = dash.Dash(
    __name__,
    external_stylesheets=[
        dbc.themes.FLATLY,
        dbc.icons.BOOTSTRAP,
    ],
    use_pages=True,
)

sidebar = dbc.Col(
    id="sidebar",
    children=[
        dbc.Nav(
            id="sidebar-nav",
            children=[
                dbc.NavLink(children="page1", id="page1", href="/page1", active="exact"),
                dbc.NavLink(children="page2", id="page2", href="/page2", active="exact")
            ],
        ),
    ],
)

main_content = dbc.Col(
    id="main-content",
    className="main-content-expanded",
    children=dash.page_container,
)

page = dbc.Row(
    id="page",
    children=[
        sidebar,
        main_content,
    ],
)

url = dcc.Location(id="url", refresh=False)

# App layout
app.layout = html.Div(
    id="layout",
    children=[page, url],
)

if __name__ == "__main__":
     app.run_server(
        debug=True,
        host=0.0.0.0,
        port=8080,
    )

pages/page1.py

import dash
import dash_bootstrap_components as dbc
from dash import MATCH, Input, Output, Patch, State, callback, html, dcc
from dash.exceptions import PreventUpdate


dash.register_page(__name__, path="/page1", name="Page1")


def make_filled_row(button_clicked: int, name: str) -> html.Tr:
    """
    Creates a filled row in the table, with dynamic id using the button_clicked
    parameter.
    """
    return html.Tr(
        [
            html.Td(name),
            html.Td(
                html.Button(
                    "Delete",
                    id={"index": button_clicked, "type": "delete"},
                    className="delete-user-btn",
                )
            ),
        ],
        id={"index": button_clicked, "type": "table-row"},
    )


header = [
    html.Thead(
        html.Tr(
            [
                html.Th("First Name"),
                html.Th(""),
            ]
        ),
        id="table-header",
    )
]


add_row = html.Tr([
    html.Td(dcc.Input(id="name-input")),
    html.Td(html.Button("Add", id="add-user-btn",)),
])

body = [html.Tbody([add_row], id="table-body")]

table = html.Table(header + body)


# Layout of the page
layout = dbc.Container([
    dbc.Row([dbc.Col([table])]),
])

# List of callbacks for the page
@callback(
    Output("table-body", "children", allow_duplicate=True),
    Output("name-input", "value"),
    Input("add-user-btn", "n_clicks"),
    State("name-input", "value"),
    prevent_initial_call=True,
)
def on_add(n_clicks: int, name: str):
    """Adds a new row to the table, and clears the input fields"""
    table_body = Patch()
    table_body.append(make_filled_row(n_clicks, name))

    return table_body, ""


@callback(
    Output({"index": MATCH, "type": "table-row"}, "children"),
    Input({"index": MATCH, "type": "delete"}, "n_clicks"),
    prevent_initial_call=True,
)
def on_delete(n_clicks: int) -> html.Tr:
    """Deletes the row from the table"""
    if not n_clicks:
        raise PreventUpdate

    return html.Tr([])

pages/page2.py

import dash
import dash_bootstrap_components as dbc
from dash import html
dash.register_page(__name__, path="/page2", name="Page2")

# Layout of the page
layout = dbc.Container([
    dbc.Row([dbc.Col(html.Div("You are on page 2"))]),
])
python plotly-dash
© www.soinside.com 2019 - 2024. All rights reserved.