为什么R Shiny中observeEvent的else if语句无法正常生效?
问题根源
- Shiny的
actionButton返回值为累计点击次数,初始为0,每点击一次数值+1 - 只要曾经点击过
btn1,input$btn1的取值就≥1,R中非0数值会被判定为TRUE,因此if(input$btn1)判断永远优先命中,else if分支永远不会被触发 - 你使用
input$btn1 | input$btn2作为触发条件时,没有额外判断本次到底是哪个按钮触发了事件,直接用累计点击次数做逻辑判断必然会出现冲突
修复方案
最简单的实现是将两个按钮的监听逻辑分开,避免判断冲突,示例修正代码如下:
library(shiny) library(shinydashboard) library(dplyr) # 原代码缺失dplyr包加载,补上避免语法报错 df <- data.frame( "obs" = 1:26, "letters" = LETTERS ) ui <- dashboardPage( dashboardHeader(), dashboardSidebar(), dashboardBody( fluidRow( box( textInput("txt", "", value = ""), actionButton("btn1", "btn1"), actionButton("btn2", "btn2") ), box( dataTableOutput("tbl") ) ) ) ) server <- function(input, output, session) { rndDF <- reactiveVal(data.frame()) # 单独监听btn1点击 observeEvent(input$btn1, { updateTextInput(session, "txt", value = sample(df$letters, 1)) dt <- df %>% filter(letters == input$txt) %>% mutate(status = "ok") rndDF(rbind(rndDF(), dt)) }) # 单独监听btn2点击 observeEvent(input$btn2, { updateTextInput(session, "txt", value = sample(df$letters, 1)) dt <- df %>% filter(letters == input$txt) %>% mutate(status = "---") rndDF(rbind(rndDF(), dt)) }) output$tbl <- renderDataTable({ rndDF() }) } shinyApp(ui, server)
如果希望保留统一的触发逻辑,也可以通过记录按钮上次点击值的方式判断本次触发源,不过拆分监听的方案代码更简洁易维护,更推荐使用。
内容的提问来源于stack exchange,提问作者youraz
相关产品推荐
相关产品推荐

