首页 > 解决方案 > ignoreInit 不适用于动态内容

问题描述

这是来自github的交叉帖子,以获得更多关注。

我认识到这observeEvent是在动态创建 UI 时在启动时触发的,即使使用ignoreInit=TRUE. 我在stackoverflow上找到了这个线程,但是提出的解决方案不起作用,checkboxInput因为 the 的值eventExpr是 either 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)

标签: rshinyshiny-reactivity

解决方案


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

我猜observeEvent在初始化时确实被阻塞了。但在那之后你渲染了 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)

推荐阅读