【问题标题】:how to delete an input in shiny renderUI?如何删除闪亮的renderUI中的输入?
【发布时间】:2015-02-25 00:27:14
【问题描述】:

在我闪亮的应用程序中,我有一个使用 renderUI 的动态输入。

这很好用,程序的另一部分捕获了滑块的输入。

当应用程序状态更改时(例如,当按下“更新模型”按钮时)我仍然需要显示/使用具有相似标签的滑块,但由于它们是“新的”,因此需要将值重新初始化为零。

问题是滑块有记忆。如果我重复使用相同的 inputId

  paste0(Labv[i], "_v",buttn)

shiny 将具有与之关联的旧值。

目前我的代码正在使用变量buttn 来绕过问题:每次状态更改时,我都会创建“新”滑块。

另一方面,用户使用应用程序的次数越多,被收集到shiny中的垃圾就越多。

我尝试使用renderUI将元素列表发送到NULL,尝试发送一个列表

updateTextInput(session, paste0(lbs[i],"_v",buttn),
            label = NULL,  value = NULL )

tags$div("foo", NULL),但在每种情况下,实际变量都呈现为文本,这是最糟糕的!

# Added simplified example
library(shiny)
library(data.table)

#
dt_ = data.table( Month = month.abb[1:5],
A=rnorm(5, mean = 5, sd = 4),
B=rnorm(5, mean = 5, sd = 4),
C=rnorm(5, mean = 5, sd = 4),
D=rnorm(5, mean = 5, sd = 4),
E=rnorm(5, mean = 5, sd = 4))

dt_[,id :=.I]
dt <- copy(dt_)
setkey(dt_, "Month") 
setkey(dt, "Month")

shinyApp(
  ui = fluidPage(
fluidRow(
  column(4, 
    actionButton("saveButton", "Update Model"))),
fluidRow(
  column(6, dataTableOutput('DT')),
  column(3, br(),br(),checkboxGroupInput("pick",h6("Picker"), 
    month.abb[1:5])),  
  column(3, uiOutput('foo'))),
fluidRow(
  column(4, verbatimTextOutput('vals')))    
  ),

  server = function(session,input, output) {
    valPpu <- reactiveValues()

    valPpu$buttonF <- 1
    valPpu$dt_ <- dt_
##
  output$DT <- renderDataTable({
  if(length(input$pick) > 0 ) {
# browser()
    isolate( { labs <- input$pick } ) # 
    buttn <- valPpu$buttonF

    iter <- length(labs)   
    valLabs <- sapply(1:iter, function(i) {
            as.numeric(input[[paste0(labs[i],"_v",buttn)]]) })

    if( iter == sum(sapply(valLabs,length)) ) {        

          cPerc <- valLabs
          cPerc <- as.data.table(cPerc)
          cPercDt <- cbind(Month=labs,cPerc)

          ival <- which(dt[["Month"]] 
              %in% cPercDt[["Month"]])
          setkey(cPercDt, "Month") 
          for(j in LETTERS[1:5]) set(dt_, i=ival, 
          j=j, dt[cPercDt][[j]] * (1 + dt_[cPercDt][["cPerc"]]) )
          valPpu$dt_ <- dt_
  } }

  dt_[order(id),]
  }, options = list(
  scrollX = TRUE,
  scrollY = "250px" ,
  scrollCollapse = TRUE,
  paging = FALSE,
  searching = FALSE,
  ordering = FALSE )
)
##
  output$foo <- renderUI({
    if(is.null(input$saveButton)) { return() }
    if(length(input$pick) > 0 ) {
      labs <-  input$pick 
      iter <- length(labs)
      buttn <- isolate(valPpu$buttonF )
      valLabs <- sapply(1:iter, function(i) {
      if(is.null(input[[paste0(labs[i],"_v",buttn)]] )) {
                0
      } else {  as.numeric(input[[paste0(labs[i],"_v",buttn)]])  }
      }) 
  #
  toRender <- lapply(1:iter, function(i) {
    sliderInput(inputId = paste0(labs[i], "_v",buttn),
                label =  h6(paste0(labs[i],"")),
                min = -1,
                max = 1,
                step = 0.01,
                value = valLabs[i],
                # format = "##0.#%",
                ticks = FALSE, animate = FALSE)
                })

      toRender
    }
    })


    observe({

  if(is.null(input$saveButton)) { return() }
  if(input$saveButton < valPpu$buttonF) { return() }
  valPpu$buttonF <- valPpu$buttonF + 1
  dt <<- valPpu$dt_
# TODO: add proper saving code  
})
  }
)

在实际应用程序中,checkboxGroupInput 也是从服务器使用 renderUI 驱动的,并在按下“更新模型”时重置。此外,UI 中还有更多“事件”我没有添加到代码中。

有什么想法吗?

【问题讨论】:

  • 示例中的data.table包真的要使用吗?如果一个简单的数据框可以工作,请下次排除不相关的包。
  • @yihui 我在我的应用程序中使用了 data.table,为您提供示例的最快方法是进行一些剪切和粘贴。感谢您的耐心等待。

标签: r shiny


【解决方案1】:

所以您当前的方法实际上有效。 FWIW,滑块已从 HTML 中删除,因此您无需担心。对于存储在input 中的旧值,例如单击两次按钮时的input[['Jan_v1']](并且您只需要input[['Jan_v2']]),我不明白您为什么如此关心它们,除非您的总内存小于几千字节,因为您只需要几个字节来存储这些值。您可能无法从 input 中删除这些值,但我建议您不要在此问题上花费时间,直到它成为真正的问题。

【讨论】:

  • 添加了一段简化的代码来更好地解释我的目标
  • 能否详细说明“滑块已从 HTML 中删除”?另一方面,请考虑我的担忧源于这样一个事实,即在真实场景中,我希望用户在应用程序上工作一个小时或更长时间,并按下大量“更新模型”按钮。另一方面,如果您认为即使创建“许多”这样的数据输入也不会破坏任何东西,我很满意。感谢您的帮助。
  • 当然。我的意思是在您单击按钮后,旧的滑块已在 HTML 中删除,并生成了新的滑块。您可以在 JavaScript 控制台中通过$('#Jan_v1') 进行验证:第一次选中第一个复选框后,该元素存在;然后你点击按钮,再次运行JS代码,你会看到它消失了;生成的是一个id为Jan_v2的滑块。
猜你喜欢
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 2020-06-01
  • 2015-08-03
相关资源
最近更新 更多