我开发了一个多页Plotly Dash应用程序。在我的应用中,许多UI组件是动态创建的。根据Dash文档,可以通过为特定的回调设置prevent_initial_call=True
来防止在应用程序首次加载时执行回调。然而,这只有在所有输入和输出组件都出现在主应用布局中时才有效。当动态创建输入/输出组件时,prevent_initial_call
参数不起作用,并且在创建组件后立即触发回调。这可能会使Dash应用程序变慢,因为在动态创建组件时触发了许多回调。
是否有一个解决方案,以防止这些回调被触发时,动态添加的组件创建?
我认为当你动态返回包含在其他回调中使用的id的组件的标记时,不可能阻止回调被触发。
我可以想到两种方法来解决这个问题。
第一种方法
第一种方法是在你的回调中使用raise PreventUpdate
,这样你就可以在某些条件下防止不必要的更新。
文档中的例子:
app.layout = html.Div([
html.Button('Click here to see the content', id='show-secret'),
html.Div(id='body-div')
])
@app.callback(
Output(component_id='body-div', component_property='children'),
Input(component_id='show-secret', component_property='n_clicks')
)
def update_output(n_clicks):
if n_clicks is None:
raise PreventUpdate
else:
return "Elephants are the only animal that can't jump"
在上面的例子中,show-secret
按钮的value
属性被隐式设置为None
。回调不使用prevent_initial_call=True
,所以它会立即运行,但它使用n_clicks
是None
的事实来确定按钮之前没有被点击过。
您可以在自己的回调中使用相同的原则。根据输入的(默认)值,您可以决定回调中的其余代码是否需要运行。
第二种方法
您可以将页面的标记放在布局中,但是使用css隐藏您不想显示的基于url的页面(例如使用display: none
)。如果采用这种方法,就可以防止回调被触发。这样做的缺点是页面在布局中,您可能不希望这样。