如何 return HTML / 来自客户端回调的组件?

How to return HTML / components from clientside callbacks?

我想将常规 (Python) 回调转换为客户端。我 运行 很难输出到 children 属性 任何比简单字符串更复杂的东西。

我希望我可以用 new dash_html_components.Span() 创建一个新组件,但这会引发错误:

Error: 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:
{
  "type": "span",
  "key": null,
  "ref": null,
  "props": {
    "children": "You have clicked THE Button!"
  },
  "_owner": null
}

完整代码如下。可以像这样将字符串以外的任何内容设置到 children 中,或者我做错了什么?


import dash_html_components as html
from dash import Dash
from dash.dependencies import Output, Input


app = Dash(prevent_initial_callbacks=True)

app.layout = html.Div([
    html.Button("THE Button", id="the_button"),
    html.Div(id="the_log"),
])

app.clientside_callback(
    """
    function(n_clicks){
        
        // return "You have clicked THE Button!";  // works
        
        // return "You have clicked <strong>THE Button!</strong>";  // works, but escapes the HTML (as expected)
        
        return new dash_html_components.Span({children: "You have clicked THE Button!"});  // doesn't work
        
        // return ["You have clicked ", new dash_html_components.Strong({children: "THE Button!" })];  // the goal
    }
    """,
    Output("the_log", "children"),
    Input("the_button", "n_clicks"),
)

if __name__ == '__main__':
    app.run_server()

经过一些调试,我发现这个可以工作:

    function(n_clicks){
        return [
            "You have clicked ", 
            {
                type: "Strong", 
                namespace: "dash_html_components",
                props: {children: "THE Button"},
            }, 
            "!"
        ];
        
    }

如果您只需要编写内联 HTML 代码,您可以使用 dash-extensions 中的 Purify 组件。当您将 HTML 代码传递给它的 html 属性 时,它会内联呈现,

from dash import html, Dash, Output, Input
from dash_extensions import Purify

app = Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Click me", id="btn"), Purify(id="purify")])
app.clientside_callback("""function(n_clicks){return 'This is <b>html</b>';}""",
                        Output("purify", "html"), Input("btn", "n_clicks"))

if __name__ == "__main__":
    app.run_server()

在渲染之前,使用 DOMPurify 执行清理,因此组件的名称。