【问题标题】:Assign a stylesheet to each page in a Dash multi page app为 Dash 多页面应用程序中的每个页面分配样式表
【发布时间】:2020-06-26 07:13:25
【问题描述】:

我正在将 3 个曾经独立运行的 Dash 应用程序合并到一个多页 Dash 应用程序中。其中一个应用是使用 Dash Bootstrap 组件构建的,并使用样式表 dbc.themes.BOOTSTRAP,另外两个不使用 bootstrap,而是使用自定义 css 样式表。

我知道我可以加载两个样式表,当通过调用发生冲突时,最后一个优先:

app = dash.Dash(name, external_stylesheets=[dbc.themes.BOOTSTRAP, 'assets/custom_styles.css'])

这两个样式表不是非常兼容,并且会产生一些在实践中很难纠正的图形错误(例如元素未正确对齐)。我想尽量减少对代码的重构,并乐于保留两个样式表。

是否可以将样式表分配给架构中的应用程序,这将大大简化我的问题?架构是:

app.py

index.py
apps
|-- init.py
|-- app1.py
|-- app2.py
|-- app3.py

app1 使用引导程序,而 app2 和 app3 使用自定义样式表。如果可能的话,我怎么能说 app1 使用一个样式表而 app2 使用另一个样式表呢?

【问题讨论】:

    标签: python css plotly-dash


    【解决方案1】:

    如果发现一种使用 Javascript 和 clientside callbacks 的 hacky 解决方法。

    例如,假设custom_styles.css 与此处的引导样式发生冲突:

    .btn-primary {
      background-color: red;
    }
    

    dbc.Button 也有一个设置background-colorbtn-primary 类,因此上面的样式会覆盖 Bootstrap 中的background-color

    您可以做的是在返回布局之前根据当前 url pathname 在文档中动态设置样式表。

    可能看起来像这样:

    import dash_html_components as html
    import dash_bootstrap_components as dbc
    import dash_core_components as dcc
    from dash import Dash
    from dash.dependencies import Output, Input
    
    app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
    app.layout = html.Div(
        [
            dcc.Location(id="url", refresh=False),
            html.Div(id="page-content"),
            dcc.Store(id="pathname"),
        ]
    )
    
    app1_layout = dbc.Button("Button", color="primary")
    app2_layout = html.Button("Button", className="primary")
    
    app.clientside_callback(
        """
        function(pathname) {
          document.querySelectorAll('link[rel="stylesheet"]').forEach(stylesheet => {
            stylesheet.remove()
          })
          const link = document.createElement('link')
          link.setAttribute("rel", "stylesheet")
          if (pathname == "/page-2") {
            link.setAttribute("href", "/assets/custom_styles.css")
          } else {
            link.setAttribute("href", "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css")
          }
          document.head.append(link)
    
          return pathname
        }
        """,
        Output("pathname", "data"),
        Input("url", "pathname"),
    )
    
    
    @app.callback(
        Output("page-content", "children"),
        Input("pathname", "data"),
    )
    def display_page(pathname):
        if pathname == "/page-2":
            return app2_layout
    
        return app1_layout
    
    
    if __name__ == "__main__":
        app.run_server()
    

    当路径名更改并输出到Store 组件的data 属性时,将执行客户端回调。返回布局的常规回调将此属性作为输入,因此回调将在更改时触发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      • 2012-02-07
      • 1970-01-01
      • 2023-03-27
      • 2015-04-13
      • 1970-01-01
      • 2021-09-21
      相关资源
      最近更新 更多