flexdashboard+Shiny:隐藏/显示section后valueBox值不更新问题求助
解决flexdashboard中valueBox section动态显示/隐藏的问题
方法一:用Shiny原生条件控制(最稳妥)
别折腾JS了,直接用Shiny的conditionalPanel把整个section包起来,根据数值动态控制显示,完全不会有更新失效的问题。
示例代码:
--- title: "动态模块演示" output: flexdashboard::flex_dashboard: orientation: columns vertical_layout: fill runtime: shiny --- ```{r setup, include=FALSE} library(flexdashboard) library(shiny)
Column {data-width=350}
输入选择
selectInput("num_choice", "选个数值:", choices = c(0, 15, 30))
动态显示的统计模块
# 先定义要显示的数值 current_val <- reactive({ as.numeric(input$num_choice) }) # 把数值判断结果注册成Shiny输出,供条件面板使用 output$display_flag <- reactive({ current_val() != 0 }) # 用conditionalPanel包裹整个section,只有数值不为0时才显示 conditionalPanel( condition = "output.display_flag", renderValueBox({ valueBox( value = current_val(), caption = "实时数值", icon = "fa-bar-chart" ) }) )
方法二:修正你的JS代码(如果非要用JS)
要是你不想改R代码结构,那得给JS加个监听逻辑,让它每次Shiny更新数值时都重新检查,而且别把DOM元素删掉,只改显示状态。
把这段JS放在你的.rmd文件开头的<script>标签里:
// 监听Shiny的数值更新事件,每次值变化都重新检查 $(document).on("shiny:value", function(e) { // 只处理valueBox的更新 if ($(e.target).hasClass("value-box")) { const valText = $(e.target).find(".value").text(); const numVal = parseInt(valText); // 找到当前对应的section(flexdashboard中section是.level3类元素) const section = $(e.target).closest(".level3"); numVal === 0 ? section.hide() : section.show(); } }); // 页面加载完成后先执行一次初始检查 $(document).ready(function() { $(".value-box").each(function() { const valText = $(this).find(".value").text(); const numVal = parseInt(valText); const section = $(this).closest(".level3"); if (numVal === 0) section.hide(); }); });
对应的R代码正常编写即可:
--- title: "动态模块演示" output: flexdashboard::flex_dashboard: orientation: columns vertical_layout: fill runtime: shiny --- <script> // 上面的JS代码粘贴到这里 </script> ```{r setup, include=FALSE} library(flexdashboard) library(shiny)
Column {data-width=350}
输入选择
selectInput("num_choice", "选个数值:", choices = c(0, 15, 30))
动态显示的统计模块
renderValueBox({ valueBox( value = as.numeric(input$num_choice), caption = "实时数值", icon = "fa-bar-chart" ) })
## 为啥原来的JS会失效? 大概率是你原来的JS只在页面加载时执行了一次,没监听Shiny后续的数值更新;或者隐藏section时直接删除了DOM元素,导致Shiny找不到对应节点更新数值。上面的JS只通过`hide()`/`show()`控制显示状态,保留完整DOM结构,同时添加了更新监听,就能解决数值无法恢复的问题。 内容的提问来源于stack exchange,提问作者Ben Nutzer
相关产品推荐
相关产品推荐

