Python plotly Dash 更新/刷新布局

too*_*s92 3 python plotly-dash

我有layout从第二个模块导入的应用程序,然后在返回app.layout到此选项卡内容时将其呈现在选项卡中。我有问题,布局是用输入的默认值导入的,当我输入填充了键并在选项卡之间更改时,当我单击回输入选项卡时,值会重置为默认值“x”。我设法通过在回调中第二次声明布局来解决这个问题,但它看起来不太好,并且需要为进一步的功能编写两次布局。有我的代码:

if 'manager' not in vars():
    manager = Recognition('xx', 'xx')
    print('defining manager')

lcheck = 0
while lcheck == 0:
    layout = [
        html.Div([
            html.Div(
                [
                    html.H3("Primary API key"),
                    dcc.Input(
                        id='primary-key',
                        value=manager.api_key,
                        placeholder='Enter a value...',
                        type='text',
                        style = {"width":"50%"}
                    ),
                    html.H3("Private API key"),
                    dcc.Input(
                        id='private-key',
                        value=manager.api_secret,
                        placeholder='Enter a value...',
                        type='text',
                        style = {"width":"50%"}
                    ),


                ],
            ),
            html.Button('Submit', id='button', className='btn btn-primary'),
            html.Div(id='output-hidden')
        ])
    ]
    lcheck=1


@app.callback(
    Output('primary-key', 'value'),
    [Input('button', 'n_clicks')],
    [State('primary-key', 'value'), 
     State('private-key', 'value')]
)
def update_output(n_clicks, value1, value2):
    values = {'value1':value1, 'value2':value2}
    global manager
    global layout
    manager.update(value1, value2)
    layout = [
        html.Div([
            html.Div(
                [
                    html.H3("Primary API key"),
                    dcc.Input(
                        id='primary-key',
                        value=manager.api_key,
                        placeholder='Enter a value...',
                        type='text',
                        style = {"width":"50%"}
                    ),
                    html.H3("Private API key"),
                    dcc.Input(
                        id='private-key',
                        value=manager.api_secret,
                        placeholder='Enter a value...',
                        type='text',
                        style = {"width":"50%"}
                    ),


                ],
            ),
            html.Button('Submit', id='button', className='btn btn-primary'),
            html.Div(id='output-hidden')
        ])
    ]

    lcheck=0
    return values['value1']
Run Code Online (Sandbox Code Playgroud)

如您所见,每次我使用按钮发送新数据时,它都会保存新布局,但此解决方案看起来很糟糕,我想找到更好的解决方案,而代码中不会出现混乱。整件事是更新value=manager.api_key,value=manager.api_secret,布局变量。我正在考虑像从正常那样访问值,list但这是不可能的,因为它不是作为常规列表嵌套的。有没有办法访问例如layout.getid("primary-key").value或类似的值?如何清理这段代码?

too*_*s92 6

我已经想出了如何解决这个问题。当我的应用程序app.layout每次选择一个选项卡时都会渲染,因此它总是渲染layout在第一次导入期间分配的。首先,我想在回调函数中每次都覆盖布局,但是写layout=2 次是没有意义的。所以我在破折号中找到了docs一个dash core component命名的dcc.Store(它将 json 存储在隐藏的 div 中)。我是这样用的:

html.Div([
        dcc.Store(id='storage')
    ],
            id="hiddendata",
            style={"display": "none"},
    ),
Run Code Online (Sandbox Code Playgroud)

该 div 直接放置在“Tabs”div 之后,并作为选项卡的“缓存”内存来记住以前的状态。最后,我更新了dcc.Store每次发送新密钥时更改数据的回调,因此当我离开选项卡时,其他选项卡知道那里有什么:

@app.callback(
    Output('storage', 'data'),
    [Input('button', 'n_clicks')],
    [State('primary-key', 'value'), 
     State('private-key', 'value')]
)
def update_output(n_clicks, value1, value2):
    values = {'value1':value1, 'value2':value2}
    global manager
    global layout
    manager.update(value1, value2)
    lcheck=0
    return values

@app.callback(
    Output('primary-key', 'value'),
    [Input('storage', 'data')],
    [State('storage', 'data')])
def update_values(values, value):
    if values:
        return value['value1']

@app.callback(
    Output('private-key', 'value'),
    [Input('storage', 'data')],
    [State('storage', 'data')])
def update_values(values, value):
    if values:
        return value['value2']
Run Code Online (Sandbox Code Playgroud)