ignoreInit无法处理动态内容

时间:2019-01-18 09:48:10

标签: r shiny shiny-reactivity

这是来自github的交叉发布,以吸引更多关注。

我认识到observeEvent是在动态创建UI时启动时触发的,即使使用ignoreInit=TRUE也是如此。我在stackoverflow上找到了该线程,但是提出的解决方案不适用于checkboxInput,因为eventExpr的值要么为T/F,所以无法确定是否为初始化或常规调用中的第一个调用。

在下面的最小工作示例中,我通过使用shinyjs::delay找到了一种解决方法,但是我不确定这是否总是可行以及所需的最短延迟时间。

对我来说,ignoreInit也应适用于动态UI,即dynamicBox的观察者不应像staticBox那样在初始化时被触发。有机会解决该问题还是这种预期的行为?

library(shinydashboard)
library(shiny)
library(shinyjs)

ui <- dashboardPage(
  dashboardHeader(title = "observeEvent ignoreInit"),
  dashboardSidebar(),
  dashboardBody(
    useShinyjs(),
    checkboxInput("staticBox", "static"),
    uiOutput("body"))
)

server <- function(input, output, session) {

  output$body <- renderUI( tagList(
    checkboxInput("dynamicBox", "dynamic"),
    checkboxInput("dynamicBoxDelayed", "dynamic delayed")
  ))

  # observe static checkBox
  observeEvent(input$staticBox, {
    cat("observeEvent of static checkBox is executed\n")
  }, ignoreInit=TRUE)

  # observe dynamic checkBox
  observeEvent(input$dynamicBox, {
    # this is executed upon start, although ignoreInit is set to TRUE
    cat("observeEvent of dynamic checkBox is executed\n")
    cat( paste0("dynamicBox value = '", input$dynamicBox, "'\n") )
  }, ignoreInit=TRUE)

  # observe dynamicDelayed checkBox
  shinyjs::delay(100, {
    observeEvent(input$dynamicBoxDelayed, {
      cat("observeEvent of dynamic checkBoxDelayed is executed\n")
    }, ignoreInit=TRUE)
  })

}

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:0)

不幸的是,由于缺少声誉,我无法发表评论,但这是我的想法:

我猜观察事件确实在初始化时被阻塞了。但是之后,您将渲染UI元素。 input $ dynamicBox从NULL更改为FALSE,这会触发observeEvent函数。

您可以通过在会话中引入唯一的全局变量来伪造该行为,比如说unique_init_variable <<-FALSE,然后在使用复选框后将其更改为true。这是示例代码

library(shinydashboard)
library(shiny)
library(shinyjs)

ui <- dashboardPage(
  dashboardHeader(title = "observeEvent ignoreInit"),
  dashboardSidebar(),
  dashboardBody(
    useShinyjs(),
    checkboxInput("staticBox", "static"),
    uiOutput("body"))
)

server <- function(input, output, session) {

  # unique init variable
  unique_init_variable <<- FALSE

  output$body <- renderUI( tagList(
    checkboxInput("dynamicBox", "dynamic"),
    checkboxInput("dynamicBoxDelayed", "dynamic delayed")
  ))

  # observe static checkBox
  observeEvent(input$staticBox, {
    cat("observeEvent of static checkBox is executed\n")
  }, ignoreInit=TRUE)

  # observe dynamic checkBox
  observeEvent(input$dynamicBox, {
    if (input$dynamicBox == TRUE) {
      unique_init_variable <<- TRUE
    }
    if (unique_init_variable) {
      # this is executed upon start, although ignoreInit is set to TRUE
      cat("observeEvent of dynamic checkBox is executed\n")
      cat( paste0("dynamicBox value = '", input$dynamicBox, "'\n") )
    }
  }, ignoreInit=TRUE)

  # observe dynamicDelayed checkBox
  shinyjs::delay(100, {
    observeEvent(input$dynamicBoxDelayed, {
      cat("observeEvent of dynamic checkBoxDelayed is executed\n")
    }, ignoreInit=TRUE)
  })

}

shinyApp(ui, server)