Dash 客户端 JS 未在页面上执行 return

Dash client-side JS not executing on page return

我有一个 dash 应用程序,我在按钮上的 print.window 添加了一个 JS 代码。该代码在多页应用程序的每一页上以及在页面上多次打印时都可以正常工作,但是一旦我迁移回我之前点击按钮的页面,它就无法工作。这会是 JS 没有执行的问题吗?或者是其他东西?代码应执行 'on click',而不是 n_clicks 计数,因此无需将任何内容重置为零。谢谢

from dash import Dash, dcc, html, Input, Output, callback
import dash_bootstrap_components as dbc

app = Dash(__name__, suppress_callback_exceptions=True)

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])


index_page = html.Div([
    dcc.Link('Go to Page 1', href='/page-1'),
    html.Br(),
    dcc.Link('Go to Page 2', href='/page-2'),
])

page_1_layout = html.Div([
    html.H1('Page 1'),
    html.Div(id='hidden-content'),
    dbc.Button('Print', id='printing', color="#D3D3D3", outline=False, style={"background": "transparent",
                                                                              'color': 'grey',
                                                                              'border': '0px'},
               className="mr-1"),
    html.Div(id='page-1-content'),
    html.Br(),
    dcc.Link('Go to Page 2', href='/page-2'),
    html.Br(),
    dcc.Link('Go back to home', href='/'),
])

@callback(Output('page-1-content', 'children'),
              [Input('page-1-dropdown', 'value')])
def page_1_dropdown(value):
    return f'You have selected {value}'


page_2_layout = html.Div([
    html.H1('Page 2'),
    dbc.Button('Print', id='printing', color="#D3D3D3", outline=False, style={"background": "transparent",
                                                                              'color': 'grey',
                                                                              'border': '0px'},
               className="mr-1"),
    html.Div(id='page-2-content'),
    html.Br(),
    dcc.Link('Go to Page 1', href='/page-1'),
    html.Br(),
    dcc.Link('Go back to home', href='/')
])

@callback(Output('page-2-content', 'children'),
              [Input('page-2-radios', 'value')])
def page_2_radios(value):
    return f'You have selected {value}'


# Update the index
@callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/page-1':
        return page_1_layout
    elif pathname == '/page-2':
        return page_2_layout
    else:
        return index_page
    # You could also return a 404 "URL not found" page here


app.clientside_callback(
    """
(function() {
    registerPrintButtonHandler();
    return;

    function registerPrintButtonHandler() {
        var button = document.getElementById("printing");

        if (!button || button.onclick === onPrintButtonClick) {
            setTimeout(registerPrintButtonHandler, 500);
            return;
        }

        button.onclick = onPrintButtonClick;
    }

    function onPrintButtonClick() {
    {
    setTimeout(window.print, 700);
};
    }
})();
    """,
    Output('blank-output2', 'children'),
    Input('printing', 'value')
)

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

我认为问题是由您在 JavaScript 层中执行的复杂的自定义事件注册引起的。在 Dash 中,通常建议将回调直接附加到相关属性。对于您的情况,这样的回调可能是,

app.clientside_callback("""function(n_clicks){
    if(n_clicks){setTimeout(window.print, 700)};
}""", Output("dummy", "children"), Input("printing", "n_clicks"))

其中输出是我添加到布局中的虚拟元素,

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content'),
    html.Div(id='dummy')
])

为了完整性,这里是完整的代码,

from dash import Dash, dcc, html, Input, Output, callback
import dash_bootstrap_components as dbc

app = Dash(__name__, suppress_callback_exceptions=True)

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content'),
    html.Div(id='dummy')
])

index_page = html.Div([
    dcc.Link('Go to Page 1', href='/page-1'),
    html.Br(),
    dcc.Link('Go to Page 2', href='/page-2'),
])

page_1_layout = html.Div([
    html.H1('Page 1'),
    html.Div(id='hidden-content'),
    dbc.Button('Print', id='printing'),
    html.Div(id='page-1-content'),
    html.Br(),
    dcc.Link('Go to Page 2', href='/page-2'),
    html.Br(),
    dcc.Link('Go back to home', href='/'),
])


@callback(Output('page-1-content', 'children'),
          [Input('page-1-dropdown', 'value')])
def page_1_dropdown(value):
    return f'You have selected {value}'


page_2_layout = html.Div([
    html.H1('Page 2'),
    dbc.Button('Print', id='printing'),
    html.Div(id='page-2-content'),
    html.Br(),
    dcc.Link('Go to Page 1', href='/page-1'),
    html.Br(),
    dcc.Link('Go back to home', href='/')
])


@callback(Output('page-2-content', 'children'),
          [Input('page-2-radios', 'value')])
def page_2_radios(value):
    return f'You have selected {value}'


# Update the index
@callback(Output('page-content', 'children'),
          [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/page-1':
        return page_1_layout
    elif pathname == '/page-2':
        return page_2_layout
    else:
        return index_page
    # You could also return a 404 "URL not found" page here


app.clientside_callback("""function(n_clicks){
    if(n_clicks){setTimeout(window.print, 700)};
}""", Output("dummy", "children"), Input("printing", "n_clicks"))

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