为什么这不起作用?
from bokeh.models.widgets import TextInput, Button
from bokeh.layouts import column
from bokeh.resources import CDN
from bokeh.embed import file_html
from bokeh.models.callbacks import CustomJS
# Create html page with a button and a textinput
bt = Button(label='Remove the text field!')
ti = TextInput(title='A text input field')
callback = CustomJS(args=dict(ti=ti), code=""" ti.parentNode.removeChild(ti); """)
bt.js_on_click(callback)
ly = column([bt, ti])
# Write to file
html = file_html(ly, CDN, "my page")
with open('/path/to/file.html', 'w') as f:
f.write(html)
它创建一个带有按钮和文本字段的网页。单击该按钮时,文本字段应该消失。
回调确实被调用(你可以用代码=&#34替换参数代码; ti.placeholder ='例如'",你看到了占位符文本更改)。
散景劫持我改变DOM的能力?更重要的是,如何使用CustomJS添加/删除/替换小部件?我无法使用常规python方法来替换小部件,因为我无法运行服务器。我只需要在Javascript中对所有小部件添加/删除/替换操作进行硬编码,以便它在没有服务器的独立本地html页面上运行。
答案 0 :(得分:0)
Bokeh不会劫持DOM,您可以通过CustomJS
回调或任何其他JS代码访问和操作DOM。但是,在上面的代码中,ti
不是DOM元素,这就是将其传递给removeChild
无效的原因。
相反,ti
是一个散景模型,它是一个对象,除其他外,它知道如何在Bokeh服务器上下文中自动同步到它的Python对应物。 ti
模型有一个视图,它有一个DOM元素。我想你可以尝试用JS DOM调用手动删除它,但我不推荐它。这不会清理模型,这可能仍然会响应各种事件,并可能是微妙问题的根源。此外,没有一种简单的方法来获取视图,您必须搜索整个DOM(视图引用了它们的模型,但模型没有对任何视图的引用)。
如果使用Bokeh服务器,我建议只更新column
个孩子以删除文本输入模型。但是我无法在CustomJS
回调中从纯JS中获得类似的东西,这可能表明存在错误。一般来说,Bokeh是在创建静态小部件布局的情况下创建的,尝试添加和删除小部件肯定是在推动。目前我建议如果你想要这种级别的控制,你可以考虑创建一个自定义扩展,将DOM管理封装在自定义模型的JS实现中:
https://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html