1 简介
这是我的系列教程Python+Dash快速web应用开发的第五期,在上一期的文章中,我们针对Dash中有关回调的一些技巧性的特性进行了介绍,使得我们可以更愉快地为Dash应用编写回调交互功能。
而今天的文章作为回调交互系统性内容的最后一期,我将带大家get一些Dash中实际应用效果惊人的高级回调特性,系好安全带,我们起飞~
图1
2 Dash中的高级回调特性
2.1 控制部分回调输出不更新
在很多应用场景下,我们给某个回调函数绑定了多个Output(),这时如果这些Output()并不是每次触发回调都需要被更新,那么就可以根据Input()值的不同,来配合dash.no_update作为对应Output()的返回值,从而实现部分Output()不更新,譬如下面的例子:
app1.py
import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
from dash.dependencies import Input, Output
import time
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.Br(),
html.Br(),
html.Br(),
dbc.Row(
dbc.Col(
dbc.Button('按钮',
color='primary',
id='button',
n_clicks=0)
)
),
html.Br(),
dbc.Row(
[
dbc.Col('尚未触发', id='record-1'),
dbc.Col('尚未触发', id='record-2'),
dbc.Col('尚未触发', id='record-n')
]
)
]
)
)
@app.callback(
[Output('record-1', 'children'),
Output('record-2', 'children'),
Output('record-n', 'children'),
],
Input('button', 'n_clicks'),
prevent_initial_call=True
)
def record_click_event(n_clicks):
if n_clicks == 1:
return (
'第1次点击:{}'.format(time.strftime('%H:%M:%S', time.localtime(time.time()))),
dash.no_update,
dash.no_update
)
elif n_clicks == 2:
return (
dash.no_update,
'第2次点击:{}'.format(time.strftime('%H:%M:%S', time.localtime(time.time()))),
dash.no_update
)
elif n_clicks >= 3:
return (
dash.no_update,
dash.no_update,
'第3次及以上点击:{}'.format(time.strftime('%H:%M:%S', time.localtime(time.time()))),
)
if __name__ == '__main__':
app.run_server(debug=True)
图2
可以观察到,我们根据n_clicks数值的不同,在对应各个Output()返回值中对符合条件的部件进行更新,其他的都用dash.no_update来代替,从而实现了局部更新,非常实用且简单。
2.2 基于模式匹配的回调
这是Dash在1.11.0版本开始引入的新特性,它所实现的功能是将多个部件绑定组织在同一个id属性下,这听起来有一点抽象,我们先从一个形象的例子来出发:
假如我们要开发一个简单的记账应用,它通过第一排若干Input()部件及一个Button()部件来记录并提交每笔账对应的相关信息,并且在最下方输出已记录账目金额之和:
app2.py
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ALL
import re
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Br(),
html.Br(),
dbc.Container(
dbc.Row(
[
dbc.Col(
dbc.InputGroup(