Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[BUG] dcc.Patch() wipes persistence of sibling pattern-matching elements

未关闭
#3,937 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
52/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
python
领域
frontend

调研方向

首先使用 Dash 4.4.0 运行 issue 中的最小 Dash 应用,然后跟踪 dcc.Patch() 如何更新带有 pattern-matching IDs 的 children,以及 persistence 如何恢复。完成标准是:追加一个新的 sibling 后,现有 pattern-matched inputs 的本地 persistence 得以保留,同时不相关的 persistence 保持不变。

由索引模型根据 Issue 内容生成。

描述

bug P2 size: 1

Sibling of: https://github.com/plotly/dash/issues/3681
Environment

dash                 4.4.0

When patching a new element to list of elements with pattern matched ids, persistence is wiped from all sibling IDs.

Minimal example:

from dash import ALL, Dash, Input, Output, Patch, dcc, html, clientside_callback, callback

app = Dash(__name__)

def make_input(index):
    return dcc.Input(
        id={"type": "inp", "index": index},
        value="initial",
        persistence=True,
        persistence_type="local",
    )


app.layout = html.Div(
    [
        html.Button("add", id="add"),
        html.Button("clear", id="clear"),
        html.Div([make_input(0), make_input(1)], id="container"),
        html.Div(id="display"),
        html.Pre(id="storage"),
        dcc.Interval(id="local_storage_poll", interval=250),
        dcc.Input("Hello, I don't wipe", id='non-pattern-matching-id', persistence=True, persistence_type='local')
    ]
)


@callback(
    Output("container", "children"),
    Input("add", "n_clicks"),
    prevent_initial_call=True,
)
def add_input(n):
    patch = Patch()
    patch.append(make_input(n + 1))
    return patch


@callback(Output("display", "children"), Input({"type": "inp", "index": ALL}, "value"))
def show(values):
    return "|".join(values)


# Debug info, show local storage to make it easier to noticed when it's wiped
clientside_callback(
    """
    function display_persisted_vals() {
        return Object.keys(window.localStorage)
            .filter(k => k.startsWith('_dash_persistence.'))
            .map(k => k + ' = ' + window.localStorage.getItem(k))
            .join('\\n') || '(nothing persisted)';
    }
    """,
    Output("storage", "children"),
    Input("local_storage_poll", "n_intervals"),
)

# Debug helper, clear local storage to do a clean test
# (helpful after the fix when the storage doesn't wipe constantly, lol)
clientside_callback(
    """
    function clear_persistence() {
        Object.keys(window.localStorage)
            .filter(k => k.startsWith('_dash_persistence.'))
            .forEach(k => window.localStorage.removeItem(k));
        window.location.reload();
        return window.dash_clientside.no_update;
    }
    """,
    Output("clear", "n_clicks"),
    Input("clear", "n_clicks"),
    prevent_initial_call=True,
)


if __name__ == "__main__":
    app.run(debug=True)

Here is a run of the minimal example app

Persistence works without a patch.
When a patch is applied persistence is wiped from siblings, but not from unrelated elements.

主要语言
Python
星标
24.4k
派生
2.3k
平均合并
1 天 19 小时
30 天内合并 PR
19

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

plotly/dash 的其他 Issue

查看 plotly/dash 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。