闪亮的复选框观察事件陷入无限循环

时间:2017-06-19 09:12:14

标签: r event-handling shiny

我有一个非常有趣的问题。我有许多复选框用于输入Shiny(自然),一切正常,如果我点击一个复选框并等待半秒然后点击下一个(屏幕变暗灰色然后复选框被选中,我可以继续)。但是,如果我在没有等待的情况下检查一个复选框(就在屏幕变为灰色之前),闪亮就会在无限循环中结束。

我无法提供完整的代码,但提供了正确的代码。

obs_ev <- "c(input[['cbox_gr1']], input[['cbox_gr2']]")

observeEvent(eval(parse(text = obs_ev)), {

dat <- eval(parse(text = obs_ev))
v1  <- input$v2
v2  <- v2_short_list[v2_list == input$v2]

# Only need the first one since v1 and v2 are the same for all inputs
dat_temp <- dat[1]

# Dataframe to update
v1_updt <- gsub("_-_", "\\2", dat_temp)
v2_updt <- gsub("_-_", "\\3", dat_temp)

focused.df      <- paste0(gsub(" ", "_", v1), "_", v2)
working.df.name <- paste0(v1_updt, "_", v2_updt)

if (focused.df == working.df.name) {

  print(dat)

  # V3 to update
  v3_updt <- gsub("_-_", "\\1", dat_temp)

  reactive.df.name <- paste0(v1_updt, "_", v2_updt, "_react")

  # Rows to update
  rows_updt <- as.numeric(gsub("_-_", "\\4", dat))

  # Update data based on checkbox input
  eval(parse(text = paste0("temp_updt <- ", working.df.name)))
  tbc <- temp_updt[[v3_updt]][!temp_updt$key %in% rows_updt]
  tbc[tbc == 2] <- 1
  temp_updt[[v3_updt]][!temp_updt$key %in% rows_updt] <- tbc
  temp_updt[[v3_updt]][rows_updt] <- 2

  # Overwrite the dataframe (not the reactive one, but instead the one that the reactive dataframe is linked to)
  eval(parse(text = paste0(working.df.name, " <<- temp_updt")))
}
})

同样,代码工作得很好,除了点击延迟 - 当我点击一个复选框时Shiny'淡入淡出'的事实,更多的是,淡入淡出并没有打扰我那么多(我希望它消失了)如果我在淡入淡出之前点击,整个事情就会在循环中结束

1 个答案:

答案 0 :(得分:0)

当遇到更新所有被动反应所花费的时间有点长并且改变输入触发某种循环时,我遇到了类似的情况。我并不总是能够解决导致它的原因。在几种情况下,我已经放弃并且只是禁用了输入控件,这样我就无法在当前更新完成之前更改输入。

您需要使用shinyjs包,并在useShinyjs()文件中加入ui功能。

我会按如下方式调整您的代码:

observe({
  ctrl <- paste0("cbox_gr", 1:2)

  lapply(ctrl,
         function(x){

           observeEvent(
             input[[x]], {

               ## DISABLE INPUT CONTROLS HERE
               lapply(ctrl, disable)

               dat <- eval(parse(text = obs_ev))
               v1  <- input$v2
               v2  <- v2_short_list[v2_list == input$v2]

               # Only need the first one since v1 and v2 are the same for all inputs
               dat_temp <- dat[1]

               # Dataframe to update
               v1_updt <- gsub("_-_", "\\2", dat_temp)
               v2_updt <- gsub("_-_", "\\3", dat_temp)

               focused.df      <- paste0(gsub(" ", "_", v1), "_", v2)
               working.df.name <- paste0(v1_updt, "_", v2_updt)

               if (focused.df == working.df.name) {

                 print(dat)

                 # V3 to update
                 v3_updt <- gsub("_-_", "\\1", dat_temp)

                 reactive.df.name <- paste0(v1_updt, "_", v2_updt, "_react")

                 # Rows to update
                 rows_updt <- as.numeric(gsub("_-_", "\\4", dat))

                 # Update data based on checkbox input
                 eval(parse(text = paste0("temp_updt <- ", working.df.name)))
                 tbc <- temp_updt[[v3_updt]][!temp_updt$key %in% rows_updt]
                 tbc[tbc == 2] <- 1
                 temp_updt[[v3_updt]][!temp_updt$key %in% rows_updt] <- tbc
                 temp_updt[[v3_updt]][rows_updt] <- 2

                 # Overwrite the dataframe (not the reactive one, but instead the one that the reactive dataframe is linked to)
                 eval(parse(text = paste0(working.df.name, " <<- temp_updt")))
               }

               ## ENABLE INPUT CONTROLS HERE
               lapply(ctrl, enable)
             })
         }
  )
})