取消时,弹出模式内的闪亮模块化输入不会写入到reactiveValue[Flexdashboard/shinydashboard] [英] Shiny modularized inputs inside pop-up modal aren't being written to reactiveValues when dismissed [flexdashboard/shinydashboard]

查看:0
本文介绍了取消时,弹出模式内的闪亮模块化输入不会写入到reactiveValue[Flexdashboard/shinydashboard]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为最小可行示例,我modularized这里的基本示例:https://rmarkdown.rstudio.com/flexdashboard/shiny.html#simple_example

代码片段(复制-粘贴,在RStudio中以.Rmd的方式运行应该可以做到这一点):

---
title: "stackoverflow example"
output: flexdashboard::flex_dashboard
runtime: shiny
---

```{r global, include=FALSE}
library(shiny)
library(flexdashboard)  # install.packages("flexdashboard")
# load data in 'global' chunk so it can be shared by all users of the dashboard
library(datasets)
data(faithful)

# UI modules
sidebarCharts <- function(id) {
  ns <- NS(id)
  tagList(
    p(),
    actionButton(ns("settings"), "Settings", icon = icon("cogs"), width = '100%', class = "btn btn-info"),p(),
    actionButton(ns("refreshMainChart") ,"Refresh", icon("refresh"), width = '100%', class = "btn btn-primary"),p()
    ,textOutput(ns("info"))  # FOR DEBUGGING
  )
}

mainChartUI <- function(id) {
  ns <- NS(id)
  plotOutput(ns("mainChart"), width = "100%")
}

# UI module for the 2 buttons in the modal:
modalFooterUI <- function(id) {
  ns <- NS(id)
  tagList(
    modalButton("Cancel", icon("remove")),
    actionButton(ns("modalApply"), "Apply", icon = icon("check"))
  )
}

server <- function(input, output, session) {

  # Init reactiveValues() to store values & debug info; https://github.com/rstudio/shiny/issues/1588
  rv <- reactiveValues(clicks = 0, applyClicks = 0,
                       bins = 20,
                       bandwidth = 1)

  # DEBUGGING
  output$info <- renderText({
    paste("You clicked the 'Settings' button", rv$clicks, "times. You clicked the 'Apply' button", rv$applyClicks, "times. The bin size is currently set to", rv$bins, "and the bandwidth is currently set to", rv$bandwidth)
  })

  settngsModal <- function(id) {
    ns <- NS(id)
    modalDialog(
      withTags({  # UI elements for the modal go in here
        fluidRow(
          column(4, "Inputs",
                 selectInput(ns("n_breaks"), label = "Number of bins:", choices = c(10, 20, 35, 50), selected = rv$bins, width = '100%')),
          column(4, "Go",
                 sliderInput(ns("bw_adjust"), label = "Bandwidth adjustment:", min = 0.2, max = 2, value = rv$bandwidth, step = 0.2, width = '100%')),
          column(4, "Here")
        )
      }),
    title = "Settings",
    footer = modalFooterUI("inputs"), 
    size = "l",
    easyClose = FALSE,
    fade = TRUE)
  }

  # Sidebar 'Settings' modal
  observeEvent(input$settings, {
    showModal(settngsModal("inputs"))  # This opens the modal; settngsModal() defined below
    rv$clicks <- rv$clicks + 1  # FOR DEBUGGING
  })

  observeEvent(input$modalApply, {
    rv$applyClicks <- rv$applyClicks + 1  # FOR DEBUGGING
    rv$bins <- input$n_breaks  # This is where I set the reactiveValues() to those inputted into the modal.
    rv$bandwith <- input$bw_adjust
    removeModal()  # This should dismiss the modal (but it doesn't seem to work)
  })

  output$mainChart <- renderPlot({
    input$refreshMainChart  # Take dependency on the 'Refresh' buton

    hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(rv$bins),  
         xlab = "Duration (minutes)", main = "Geyser Eruption Duration")

    dens <- density(faithful$eruptions, adjust = rv$bandwidth)
    lines(dens, col = "blue")
  })

}

```

Column {.sidebar}
-----------------------------------------------------------------------

```{r}
callModule(server, "main")
sidebarCharts("main")
```

Column
-----------------------------------------------------------------------

### Main chart goes here

```{r}
mainChartUI("main")
```

截图:

这是所需的功能:

  1. 在应用启动时,图表应使用rv中存储的存储箱大小和带宽的默认参数呈现,这是一个reactiveValues()--这似乎是有效的。
  2. 当我第一次单击模式时,它应该显示默认的箱大小和带宽参数--这看起来也是有效的。
  3. 当我更新其中一个输入参数单击‘Apply’时,它应该取消该模式,并随后将rvreactiveValues()对象中的各个参数设置为选定的参数--这不起作用(既不是取消模式,也不是reactiveValues被更新)。
  4. reactiveValues()内部rv更新为新图表后,在用户点击‘刷新’actionButton之前,图表不应重新呈现--这也不起作用,但取决于上面的(3)。

我做错了什么??感觉我忽略了一些非常简单的东西。

谢谢!!

推荐答案

问题源于您的模式和服务器函数具有不同的namespaceID,因此无法以正常方式相互通信。

当您使用callModule调用server函数时,您为您的模块提供了"main"的命名空间ID。当您生成您的modal时,您为它提供了"inputs"的命名空间id。因此,当您尝试使用observeEvent(input$modalApply...访问服务器中的actionButton时,它无法工作,因为它在其自己的命名空间("main")的inputs$中查找inputs$,而该命名空间并不存在。

您需要做的是将模型与调用它的服务器函数保持在相同的名称空间中。您可以通过将ns函数直接从会话传递到模式UI函数来完成此操作。

不用传入id,然后用ns <- NS(id)重新生成ns,可以直接用session$ns获取当前的会话ns函数,然后传递给UI函数使用:

observeEvent(input$settings, {
    showModal(settngsModal(session$ns))
}

...

settngsModal <- function(ns) {
    ...
    footer = modalFooterUI(ns), 
    ...
}

通过以这种方式传递session$ns,您可以确保模型的UI元素始终与调用它的服务器函数位于相同的名称空间中(因此可以访问)。您可以在此处阅读更多信息:http://shiny.rstudio.com/articles/modules.html#using-renderui-within-modules


至于第二个问题,只需将renderPlot中的其余代码包装在isolate函数中即可。isolate函数使isolate中的reactive值的更改不会使表达式无效并导致重新求值。现在,唯一可以导致renderPlot重新求值的reactive值是isolateinput$refreshMainChart

之外的值
output$mainChart <- renderPlot({
    input$refreshMainChart  # Take dependency on the 'Refresh' buton
    isolate({
        hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(rv$bins),  
             xlab = "Duration (minutes)", main = "Geyser Eruption Duration")

        dens <- density(faithful$eruptions, adjust = rv$bandwidth)
        lines(dens, col = "blue")
    })
})

这篇关于取消时,弹出模式内的闪亮模块化输入不会写入到reactiveValue[Flexdashboard/shinydashboard]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆