【问题标题】:How to reset a value of fileInput in Shiny?如何在 Shiny 中重置 fileInput 的值?
【发布时间】:2017-10-27 11:23:41
【问题描述】:

已经有关于这个问题的类似帖子(例如how can I update a shiny fileInput object?),但我仍然无法弄清楚在使用fileInput 小部件后如何迫使Shiny 忘记input$file 的值。

当一个人想用actionButton(在我的例子中称为"Submit")触发文件上传,然后用另一个actionButton(这里是"Reset")重置它的值时,这个问题就变得烦人了。 再次单击“提交”按钮时,很明显 input$file 值仍然存在。

我尝试使用一些推荐的解决方案:shinyjs 包并用renderUI/uiOutput 刷新fileInput 模块 - 但仍然没有结果。

这是我的代码:

server.R

shinyServer(function(input, output, session) {

values <- reactiveValues(
 file = NULL
)

observeEvent(input$submit, {
 values$file <- input$file1
})

observeEvent(input$reset, {
 values$file <- NULL
 output$resettableInput <- renderUI({
  fileInput('file1', label = NULL)
 })
}, ignoreNULL = F)

output$summary <- renderText({
 return(paste('Uploaded file:', values$file$name))
})
})

ui.R

shinyUI(bootstrapPage(

 headerPanel('Reset / Submit file input example'),

 sidebarPanel(

  uiOutput('resettableInput'),

  fluidRow(
          column(4,
                 actionButton('reset', 'Reset All')
          ),
          column(4,
                 actionButton('submit', 'Submit')
          )
  )
 ),

 mainPanel(
  h4('Summary'),
  verbatimTextOutput('summary')
 )
))

如果有任何帮助,我将不胜感激。

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    input$file1 被 Shiny 缓存所以在下次上传之前不会改变。

    由于您想要一个文件名变量在大多数情况下映射到input$file1$name,但在单击重置按钮时重置为NULL,您需要创建另一个层并保持这种关系。

    • 您可以创建一个变量upload_state,将其设置为带有文件上传事件的uploaded,以及带有重置按钮的reset

    • 使用响应式表达式,根据upload_state 值采用input$file1$nameNULL

    不需要submit 按钮。

    library(shiny)
    ui <- shinyUI(bootstrapPage(
      headerPanel("Reset / Submit file input example"),
      sidebarPanel(
        fileInput('file1', label = NULL),
        fluidRow(
          column(4,
                 actionButton('reset', 'Reset Input')
          ))
      ),
    
      mainPanel(
        h4("Summary"),
        verbatimTextOutput("summary")
      )
    ))
    
    server <- shinyServer(function(input, output, session) {
      values <- reactiveValues(
        upload_state = NULL
      )
    
      observeEvent(input$file1, {
        values$upload_state <- 'uploaded'
      })
    
      observeEvent(input$reset, {
        values$upload_state <- 'reset'
      })
    
      file_input <- reactive({
        if (is.null(values$upload_state)) {
          return(NULL)
        } else if (values$upload_state == 'uploaded') {
          return(input$file1)
        } else if (values$upload_state == 'reset') {
          return(NULL)
        }
      })
    
      output$summary <- renderText({
        return(paste("Uploaded file:", file_input()$name))
      })
    })
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

    • 由于单个文件的上传只是整个项目的一小部分(程序读取数据的方式多种多样,包括几个fileInputs),所以Submit按钮是一个关键元素。此外,据我所知,您的“第二层”与我的values$file 反应值具有相同的作用。无论如何,感谢您的努力!
    • @Pawel 第一个重要的区别是正确使用反应式表达,这解决了你的问题。其次,我故意从file 中选择一个不同的名称,因为您无法控制input$file1,并且您希望此变量有所不同。此外,如果我的回答解决了您的问题,您可以“接受”它作为答案并给予支持。这就是在 SO 中提问的方式。否则,您似乎认为这没有解决您的问题,仍在等待新的答案。
    • @dracodoc 更清楚一点:在我的真实应用程序中,我有多达 8 个 fileInput 小部件。我需要让用户显示和隐藏它们,并灵活地更改加载的文件。为了提高沟通效率,我需要提交按钮。例如,用户可能首先加载三个文件,但随后决定取消其中一个并保留剩下的两个。问题是第三个仍然在缓存中,因此它也会被“提交”。所以,即使我发现你的代码比我的更优雅,我也不能接受它作为正确的答案。我会投赞成票,但我的名声太弱了。
    • 那么你需要在问题中陈述完整的图片。 sumbit 按钮仍然没有意义,因为文件已经上传。要选择要在下一步使用的文件,您可以使用各种方法来选择已上传的文件,例如每个文件上传器的复选框,或显示所有上传文件的表格,选择行以删除一个用户不想要的。
    【解决方案2】:

    我知道这是一篇旧帖子,但您可以通过在服务器中从头开始重建输入来重置输入。

    在 ui.R 你可以放:

    ...
    uiOutput('file1_ui') ## instead of fileInput('file1', label = NULL)
    ...
    

    然后在 server.R 中添加:

    ...
    output$file1_ui <- renderUI({
      input$reset ## Create a dependency with the reset button
      fileInput('file1', label = NULL)
    })
    ...
    

    【讨论】:

    • 我同意这是解决诸如“如何重置 XXX?”之类的任何闪亮问题的最通用和最可靠的方法
    • 请注意,这会清除输入表单,但不会像上面那样更改 input$file1 的值,因此依赖于上传文件的内容不会失效并重新呈现。
    猜你喜欢
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 2015-11-25
    • 1970-01-01
    相关资源
    最近更新 更多