有没有办法防止回调在破折号中触发?

Is there a way to prevent a callback from firing in dash?

我有以下回调:

@app.callback(
    [Output("useridPicker", "value"), Output("datePicker", "date"), ],
    [Input("url", "search")]
)
def update_form_default(url_search):
    return 111, dt.today()


@app.callback(
    Output("url", "search"),
    [Input("useridPicker", "value"), Input("datePicker", "date")]
)
def update_current_url(userid, date):
    return f"?userid=111&date=2020-06-29"

我有一个文本区域来选择一个用户 ID (useridPicker),一个日期选择器来选择一个日期 (datePicker) 和一个包含当前用户 ID 作为参数的 url和当前日期(“YYYY-MM-DD”)。

当我修改 url 的日期或用户 ID 时,我想更新 (useridPicker) 和 (datePicker) 中显示的值。反之亦然。

现在,我收到以下错误:

Error: Dependency Cycle Found: useridPicker.value -> url.search -> useridPicker.value

在一个回调中,有没有办法阻止触发另一个回调?为了避免这种循环依赖错误和回调之间可能的无限循环。

可以通过两种方式中止 Dash 回调。您可以引发 dash.exceptions.PreventUpdate 异常以中止整个回调,或者您可以 return dash.no_update 为每个您不想更新的输出。

@emher 关于提前中止回调的选项是正确的,但这并不能解决循环回调的问题(React.js 中的限制在 dash 之下)。

关于高级回调的 dash 文档提供了一些如何避免循环回调的建议:https://dash.plotly.com/advanced-callbacks

As of dash v1.19.0, you can create circular updates within the same callback.

Circular callback chains that involve multiple callbacks are not supported.

Circular callbacks can be used to keep multiple inputs synchronized to each other.

诀窍是将您的两个回调替换为具有多个输出的单个回调,并在回调中使用 dash.callback_context.triggered 来检测哪些输入被修改以触发回调。您可以使用 no_update 仅更新需要更改的输出。像这样:

from dash import callback_context, no_update

@app.callback(
    Output("url", "search"),
    Output("useridPicker", "value"),
    Output("datePicker", "date"),
    Input("url", "search"),
    Input("useridPicker", "value"),
    Input("datePicker", "date"),
)
def update_form_default(url_search):
    changed_inputs = [
        x["prop_id"]
        for x in callback_context.triggered
    ]
    if "url.search" in changed_inputs:
        return no_update, 111, dt.today()
    else:
        return f"?userid=111&date=2020-06-29", no_update, no_update