在我的闪亮应用程序中,我使用renderUI进行动态输入。
这非常有效,程序的另一部分捕获了滑块的输入。
当应用程序更改状态时(例如,当按下按钮"更新模型"按下时)我仍然需要显示/使用具有相似标签的滑块,但它们是" new"该值需要重新初始化为零。
问题是滑块有内存。如果我重新使用相同的inputId
paste0(Labv[i], "_v",buttn)
有光泽将具有与之关联的旧值。
目前我的代码使用变量buttn
来绕过问题:每次状态更改时我都会创建" new"滑块。
另一方面,用户使用该应用程序的次数越多,收集的垃圾就越多。
我尝试使用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从服务器驱动的,并在&#34;更新模型&#34;被压了。此外,还有更多&#34;事件&#34;在用户界面中,我还没有添加到代码中。
有什么想法吗?
答案 0 :(得分:0)
因此,您当前的方法实际上有效。 FWIW,滑块已从HTML中删除,因此您无需担心。对于存储在input
中的旧值,例如input[['Jan_v1']]
,当按钮被点击两次(并且您只需要input[['Jan_v2']]
)时,我不明白为什么你如此关心它们除非你的总内存少于几千字节,因为你只需要几个字节来存储这些值。您可能无法从input
中删除这些值,但我建议您不要在此问题上花时间,直到它成为真正的问题。