Python plotly Dash updating/refreshing 布局
Python plotly Dash updating/refreshing layout
我的应用程序从第二个模块导入 layout
,然后在选项卡中将其呈现为返回 app.layout
到此选项卡内容。我有问题,布局是使用输入的默认值导入的,当我的输入充满了键并在选项卡之间切换时,当我单击返回输入选项卡时,值重置为默认值 'x'。我设法通过在回调中第二次声明布局来解决这个问题,但它看起来不太好,需要编写布局 2 次才能获得更多功能。这是我的代码:
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']
如您所见,每次我使用按钮发送新数据时,它都会保存新布局,但这个解决方案看起来很糟糕我想找到更好的解决方案,避免代码混乱。整件事就是更新布局变量中的 value=manager.api_key,
和 value=manager.api_secret,
。我正在考虑像正常 list
一样访问值,但这是不可能的,因为它没有嵌套为常规列表。有什么方法可以访问 layout.getid("primary-key").value
之类的值吗?如何清理此代码?
我已经找到解决这个问题的办法了。由于我的应用程序每次我 select 一个选项卡时都会渲染 app.layout
,所以它总是渲染在第一次导入期间分配的 layout
。首先,我想在回调函数中每次都覆盖布局,但是写 layout=
2 次是没有意义的。所以我在 dash docs
中找到了一个名为 dcc.Store
的 dash core component
(它将 json 存储在隐藏的 div 中)。我是这样使用的:
html.Div([
dcc.Store(id='storage')
],
id="hiddendata",
style={"display": "none"},
),
这个 div 直接放在 'Tabs' div 之后,作为 'cache' 选项卡的内存以记住以前的状态。最后,我更新了回调以在每次发送新密钥时更改 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']
我的应用程序从第二个模块导入 layout
,然后在选项卡中将其呈现为返回 app.layout
到此选项卡内容。我有问题,布局是使用输入的默认值导入的,当我的输入充满了键并在选项卡之间切换时,当我单击返回输入选项卡时,值重置为默认值 'x'。我设法通过在回调中第二次声明布局来解决这个问题,但它看起来不太好,需要编写布局 2 次才能获得更多功能。这是我的代码:
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']
如您所见,每次我使用按钮发送新数据时,它都会保存新布局,但这个解决方案看起来很糟糕我想找到更好的解决方案,避免代码混乱。整件事就是更新布局变量中的 value=manager.api_key,
和 value=manager.api_secret,
。我正在考虑像正常 list
一样访问值,但这是不可能的,因为它没有嵌套为常规列表。有什么方法可以访问 layout.getid("primary-key").value
之类的值吗?如何清理此代码?
我已经找到解决这个问题的办法了。由于我的应用程序每次我 select 一个选项卡时都会渲染 app.layout
,所以它总是渲染在第一次导入期间分配的 layout
。首先,我想在回调函数中每次都覆盖布局,但是写 layout=
2 次是没有意义的。所以我在 dash docs
中找到了一个名为 dcc.Store
的 dash core component
(它将 json 存储在隐藏的 div 中)。我是这样使用的:
html.Div([
dcc.Store(id='storage')
],
id="hiddendata",
style={"display": "none"},
),
这个 div 直接放在 'Tabs' div 之后,作为 'cache' 选项卡的内存以记住以前的状态。最后,我更新了回调以在每次发送新密钥时更改 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']