本文介绍了将闪亮应用程序中的所有用户输入导出到文件并稍后加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的闪亮应用程序有几个输入,用于定义生成的绘图的几个参数。用户很可能会花费几分钟时间来检查所有可能的选项,直到他对输出感到满意。显然,绘图可以不同的格式导出,但用户可能希望稍后使用不同的数据重新创建相同的绘图,或者可能只更改一个小细节。

因此,我需要为用户提供一种导出其所有设置并保留该文件以供以后使用的方法。我开发了一种方法,但效果不佳。我使用reactiveValuesToList获取所有输入元素的名称,并保存为一个格式为inputname=inputvalue的简单文本文件。这是downloadHandler上的downloadHandler

output$bt_export <- downloadHandler(
  filename = function() {
    "export.txt"
  },
  content = function(file) {
    inputsList <- names(reactiveValuesToList(input))
    exportVars <- paste0(inputsList, "=", sapply(inputsList, function(inpt) input[[inpt]]))
    write(exportVars, file)
  })

这工作得很好,但是加载不太顺利。因为我没有(也不知道如何)保存输入类型,所以我必须盲目地更新值。我是这样做的:

importFile <- reactive({
  inFile <- input$fileImport
  if (is.null(inFile))
    return(NULL)
  lines <- readLines(inFile$datapath)
  out <- lapply(lines, function(l) unlist(strsplit(l, "=")))
  return(out)
})

observe({
    imp <- importFile()
    for (inpt in imp) {
      if (substr(inpt[2], 0, 1) == "#") {
        shinyjs::updateColourInput(session, inputId = inpt[1], value = inpt[2])
      } else {
        try({
          updateTextInput(session, inputId = inpt[1], value = inpt[2])
          updateNumericInput(session, inputId = inpt[1], value = inpt[2])
          updateSelectInput(session, inputId = inpt[1], selected = inpt[2])
        })
      }
    }
  })

除了shinyjs::colorInput可以通过#启动来识别之外,我还必须使用try()来处理其他的try()。这在一定程度上是可行的,但是一些输入没有被更新。手动检查导出的文件会发现没有更新的输入在那里,所以我想一次更新100多个输入不是一个好主意。此外,try()部分看起来不太好,可能不是一个好主意。

该应用程序已接近完成,但可能会在将来进行更新,添加/更改一些输入。即使这会使一些"旧的"导出输入无效,也是可以接受的,因为我会尽量保持向后兼容性。但我正在寻找一种不只是编写数百行代码来逐个更新输入的方法。

我考虑过使用save.image(),但是简单地使用load()并不能恢复应用程序输入。我还考虑过以某种方式一次性更新所有输入,而不是逐个更新,但什么都没有想出来。有没有更好的方法将所有用户输入导出到一个文件,然后加载它们?无论是对此进行了改进,效果更好,还是采用了完全不同的方法,这都无关紧要。

推荐答案

如果您查看闪亮的输入更新函数的代码,它们会以session$sendInputMessage(inputId, message)结尾。message是需要在输入中更改的属性列表,例如,复选框输入:message <- dropNulls(list(label = label, value = value))

因为大多数输入都有value属性,所以您可以直接在所有输入上使用session$sendInputMessage函数,而不使用try

这里有一个示例,我创建了dummy_data,以便在您单击按钮时更新所有输入,其结构应该与您导出的内容类似:

ui.R

library(shiny)
shinyUI(fluidPage(
  textInput("control_label",
            "This controls some of the labels:",
            "LABEL TEXT"),
  numericInput("inNumber", "Number input:",
               min = 1, max = 20, value = 5, step = 0.5),
  radioButtons("inRadio", "Radio buttons:",
               c("label 1" = "option1",
                 "label 2" = "option2",
                 "label 3" = "option3")),
  actionButton("update_data", "Update")

  ))

server.R

library(shiny)

dummy_data <- c("inRadio=option2","inNumber=10","control_label=Updated TEXT" )

shinyServer(function(input, output,session) {
  observeEvent(input$update_data,{
    out <- lapply(dummy_data, function(l) unlist(strsplit(l, "=")))
   for (inpt in out) {
     session$sendInputMessage(inpt[1], list(value=inpt[2]))
    }
   })

})
所有update函数还在调用session$sendInputMessage之前预格式化值。我还没有尝试所有可能的输入,但至少对于这3个输入,您可以向函数传递一个字符串来更改numericInput,它仍然工作得很好。

如果某些输入有问题,您可能希望使用save保存reactiveValuesToList(input),当您希望更新输入时,使用load并在for循环中运行列表(您必须将其调整为命名列表)。

这篇关于将闪亮应用程序中的所有用户输入导出到文件并稍后加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 04:04