Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
300 views
in Technique[技术] by (71.8m points)

python - How can I have multiple Navigations for the same URL paths in Dash

I am trying to add multiple navigations for the same URL path.

my code..

import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table


app = dash.Dash()

index_layout = html.Div([
    # represents the URL bar, doesn't render anything
    dcc.Location(id='url', refresh=False),

    
    html.Br(),
    
    dcc.Link(dbc.Button('Page1',
                        color="secondary",
                        className="mr-1",
                        outline=True,
                        style={"width":400,
                        "vertical-align": "middle",
                        }
                        ), href='/page1'),
    html.Br(),html.Br(),html.Br(),html.Br(),html.Br(),
    dcc.Link(dbc.Button("Page2",
                        style={"width":400,
                        "vertical-align": "middle"},
                        color="secondary",
                        className="mr-1",
                        outline=True
                        ), href='/page2'),
    

])


page1_layout = html.H1("Page1")
page2_layout = html.H1("Page2")

app.layout = html.Div([
    dcc.Location(id='url-nav', refresh=True),

    html.Span(dbc.Nav(
    [
        dbc.NavLink(dbc.NavLink("Page1", href="/page1")),
        dbc.NavLink(dbc.NavLink("Page2", href="/page2")),

    ],

    pills=True,),
     className="ml-auto"
),
    dcc.Location(id='url', refresh=True),
    html.Center([
    html.H3('DEMO AP',id='title'),
    # content will be rendered in this element
    html.Div(id='page-content'),
    ],),
])



### CALLBACKS

@app.callback(dash.dependencies.Output('page-content', 'children'),
              [dash.dependencies.Input('url', 'pathname')])
def display_page(pathname="/"):
    
    ctx = dash.callback_context
    triggered_by = ctx.triggered[0].get("prop_id")

    if pathname == "/page1":
        return page1_layout

    elif pathname == "/page2":
        return page2_layout

    else:
        return index_layout


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

Button navigations are working fine, but html.Nav only works on the very first click, not consistent and not working on the following clicks.

Kindly help.

question from:https://stackoverflow.com/questions/65937293/how-can-i-have-multiple-navigations-for-the-same-url-paths-in-dash

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

From testing this out the problem seems to be with this line in index_layout:

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

If you look in the console you will see that a lot of requests are sent constantly when you're on the main page (when index_layout is rendered).

When this line is removed your code works as expected.

Working solution:

import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table


app = dash.Dash()

index_layout = html.Div(
    [
        html.Br(),
        dcc.Link(
            dbc.Button(
                "Page1",
                color="secondary",
                className="mr-1",
                outline=True,
                style={
                    "width": 400,
                    "vertical-align": "middle",
                },
            ),
            href="/page1",
        ),
        html.Br(),
        html.Br(),
        html.Br(),
        html.Br(),
        html.Br(),
        dcc.Link(
            dbc.Button(
                "Page2",
                style={"width": 400, "vertical-align": "middle"},
                color="secondary",
                className="mr-1",
                outline=True,
            ),
            href="/page2",
        ),
    ]
)


page1_layout = html.H1("Page1")
page2_layout = html.H1("Page2")

app.layout = html.Div(
    [
        dcc.Location(id="url-nav", refresh=True),
        html.Span(
            dbc.Nav(
                [
                    dbc.NavLink(dbc.NavLink("Page1", href="/page1")),
                    dbc.NavLink(dbc.NavLink("Page2", href="/page2")),
                ],
                pills=True,
            ),
            className="ml-auto",
        ),
        dcc.Location(id="url", refresh=True),
        html.Center(
            [
                html.H3("DEMO AP", id="title"),
                # content will be rendered in this element
                html.Div(id="page-content"),
            ],
        ),
    ]
)


### CALLBACKS


@app.callback(
    dash.dependencies.Output("page-content", "children"),
    [dash.dependencies.Input("url", "pathname")],
)
def display_page(pathname="/"):

    ctx = dash.callback_context
    triggered_by = ctx.triggered[0].get("prop_id")

    if pathname == "/page1":
        return page1_layout

    elif pathname == "/page2":
        return page2_layout

    else:
        return index_layout


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

The problem here I think is that there are two Location components rendered at the same time with the same id (url). This apparently causes the callback to be called constantly and causes inconsistent link behavior.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...