【问题标题】:Shiny: use validate() inside downloadHandler闪亮:在 downloadHandler 中使用 validate()
【发布时间】:2018-12-04 15:24:05
【问题描述】:

我有一个闪亮的应用程序,一旦单击按钮就会打印报告。通过 downloadHandler() 函数创建报告。

我希望在导出报告之前有一个强制输入字段;合适的 Shiny 函数是 validate() (https://shiny.rstudio.com/articles/validation.html)。

但是,根据文档,validate() 函数只能用于 reactive() 或 render() 函数:

To use this validation test in your app, place it at the start of any reactive or render* expression that calls input$data. 

我没有找到可以将此函数放入我的 downloadHandler 函数的地方。有人知道这怎么可能吗?

这里是相关的代码部分;我希望创建报告时必须填写“公司名称”字段。

ui <- fluidPage(

  sidebarLayout(
    position = "left",

    sidebarPanel(

      textInput(
        inputId = "company_name",
        label = "Company name", 
        value = ""
      ),
    )
  )
)

server <- function(input, output) {
  output$report <- downloadHandler(
    filename = "report.pdf",
    content = function(file) {
      # Copy the report file to a temporary directory before processing it, in
      # case we don't have write permissions to the current working dir (which
      # can happen when deployed).
      tempReport <- file.path(tempdir(), "report.Rmd")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      dir.create(file.path(tempdir(),"www"))
      file.copy("www", file.path(tempdir()), recursive=TRUE)      

      # Set up parameters to pass to Rmd document
      params <- list(company_name = input$company_name)

      # Knit the document, passing in the `params` list, and eval it in a
      # child of the global environment (this isolates the code in the document
      # from the code in this app).

      rmarkdown::render(tempReport, output_file = file,
                        params = params,
                        envir = new.env(parent = globalenv())
      )
    }
  )
}

【问题讨论】:

    标签: shiny


    【解决方案1】:

    问题在于downloadButton 是一个输入小部件,而validate 应该与输出一起使用。

    如果您的下载要求未得到满足,我的解决方法是隐藏(或禁用)downloadButton。这可以通过shinyjs 来完成,它允许您通过 id 隐藏或禁用按钮。

    library(shiny)
    
    ui <- fluidPage(
      shinyjs::useShinyjs(),
      textInput("text", "content", "", placeholder = "please insert something"),
      shinyjs::hidden(downloadButton("download"))
    )
    
    server <- function(input, output, session) {
      output$download <- downloadHandler(
        filename = "file.csv",
        content = function(file) {
          write.csv(data.frame(content = input$text), file)
        }
      )
    
      observeEvent(input$text, {
        if (input$text == "")
          shinyjs::hide("download")
        else
          shinyjs::show("download")
      })
    }
    
    shinyApp(ui, server)
    

    hide/show/hidden 替换为enable/disable/disabled 以始终显示按钮,但在input$text 为空时使其不可点击。

    【讨论】:

    • 请在shinyjs::hide/show("download") 代码行中使用“shinyjs::”前缀。
    • @Andrii 完成!我没有在新版本的答案中附加shinyjs 包。您过去是否遇到过与 hide()show() 的命名空间冲突?
    • 我刚刚发现它只适用于“shinyjs::”前缀。感谢您的建议!
    • 这很奇怪。您可能附加了一些其他包,覆盖了hide() 和/或show() 的定义。您可以使用 CRAN 包 conflicted 来进一步诊断。
    猜你喜欢
    • 2017-04-04
    • 2020-04-20
    • 2022-01-26
    • 1970-01-01
    • 2018-08-02
    • 2017-07-06
    • 2021-12-22
    • 2014-08-24
    • 2020-01-08
    相关资源
    最近更新 更多