【问题标题】:Why is updateTabsetPanel running last inside an observeEvent?为什么updateTabsetPanel 在observeEvent 中最后运行?
【发布时间】:2021-11-07 20:32:41
【问题描述】:

我期待:

  • 插入 UI 元素
  • 更新 UI 元素
  • 运行长时间计算

全部按下一个按钮。示例应用:

ui <- fluidPage(
  useShinyjs(),
  mainPanel(
    tabsetPanel(
      id = "test",
      tabPanel(
        title = "First",
        actionButton(
          "press",
          "Press Me")),
      tabPanel(
        title = "Second",
        tabsetPanel(
          id = "toinsert"
        )))
  )
  
)

server <- function(input, output, session) {
  observe({
    disable(selector = '#test a[data-value = "Second"]')
    })
  
  totest <- reactiveValues()
  totest$tab <- 0
  observeEvent(input$press,{
    enable(selector = '#test a[data-value = "Second"]')
    
    updateTabsetPanel(
      session,
      'test',
      selected = "Second"
    )
    
    totest$tab <- totest$tab + 1
    insertTab(
      session = session,
      inputId = "toinsert",
      tab = tabPanel(
        title = paste0("AA_",totest$tab),
        div(p("BBBBB"))
      )
    )
    
    updateTabsetPanel(
      session,
      'toinsert',
      selected = paste0("AA_",totest$tab)
    )
    
    totest$a <- 1    
    
  })
  
  observeEvent(totest$a,{
    if(totest$a == 1){
      Sys.sleep(5)
      print("A")
      totest$a <- 0
    }else{}
    
  })
}

shinyApp(ui, server)

运行前面的示例,您会注意到代码运行正确但出现了乱序:首先运行计算,然后更新 UI 元素。在 stackoverflow 上搜索我发现了一个类似的问题 R shiny: Update tabsetpanel before finishing all the observeEvent code 并尝试接受的答案将我的 observeEvent 代码更改为:

observeEvent(input$press,{
    enable(selector = '#test a[data-value = "Second"]')
    
    updateTabsetPanel(
      session,
      'test',
      selected = "Second"
    )
    
    totest$tab <- totest$tab + 1
    insertTab(
      session = session,
      inputId = "toinsert",
      tab = tabPanel(
        title = paste0("AA_",totest$tab),
        div(p("BBBBB"))
      )
    )
    
    updateTabsetPanel(
      session,
      'toinsert',
      selected = paste0("AA_",totest$tab)
    )
    
    
    givingvalue <- reactive({
      req(input$toinsert)
      totest$a <- 1
    })
    
    givingvalue()
    
  })

但这没有用。第一次单击按钮后,UI 更新,但长时间计算没有运行,并且在我第二次按下按钮后,它就像以前的配置一样工作。我假设再次单击按钮后正在运行计算。

为什么会这样?我该如何解决我的问题?

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    也许你正在寻找这个

    ui <- fluidPage(
      useShinyjs(),
      mainPanel(
        tabsetPanel(
          id = "test",
          tabPanel(
            title = "First",
            actionButton(
              "press",
              "Press Me")),
          tabPanel(
            title = "Second",
            tabsetPanel(
              id = "toinsert"
            )))
      )
      
    )
    
    server <- function(input, output, session) {
      # observe({
      #   disable(selector = '#test a[data-value = "Second"]')
      # })
      
      totest <- reactiveValues(tab=0,a=0)
    
      observeEvent(input$press,{
        #enable(selector = '#test a[data-value = "Second"]')
        totest$tab <- totest$tab + 1
        
        updateTabsetPanel(
          session,
          'test',
          selected = "Second"
        )
        
      })
      
      observeEvent(input$test,{
        print(input$test)
        #totest$a <- 1
        if (input$test=="Second") {
          insertTab(
            session = session,
            inputId = "toinsert",
            tab = tabPanel(
              title = paste0("AA_",totest$tab),
              div(p("BBBBB"))
            )
          )
          
          updateTabsetPanel(
            session,
            'toinsert',
            selected = paste0("AA_",totest$tab)
          )
        }
        
      })
      
      observeEvent(input$toinsert,{
        if (!is.null(input$toinsert)) {
            Sys.sleep(5)
            print("A")
        }
      }, ignoreNULL = TRUE)
      
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 感谢您的回答,它仅在我第一次按下按钮时有效。我已经解决了如下。更改第二个 observeEvent 以检查 input$toinsert。这样,在选择新添加的选项卡之前,它不会开始计算。如果您有任何其他想法或您的答案对您有用,请现在告诉我。我仍在为计算完成后闪亮更新 UI 的事实而苦苦挣扎。
    • 对不起,我在上面的代码中注释掉了错误的行。我已经更新了它。现在对我来说效果很好。
    • 在您的回答中,对 input$test 进行第二次 observeEvent 检查使得在第一个和第二个选项卡之间进行更改的事实将最后添加的选项卡添加到 toinsert tabsetPanel,但计算仅在 totest$ 时执行标签更改
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    相关资源
    最近更新 更多