【问题标题】:observeenvent with two conditions有两个条件的观察事件
【发布时间】:2018-02-10 17:37:34
【问题描述】:

我尝试在 Shiny 中嵌套一些“观察事件”来创建条件规则。

应该是这样的:

  • 如果单击一个框,则单击按钮时显示相应的单个输出。
  • 如果两个框都被单击,则在单击按钮时显示两个输出。

但它总是显示两个输出。

有什么建议吗?

shinyApp(
  ui = basicPage(
    checkboxInput("box1", label = "Checkbox1", value = FALSE),
    checkboxInput("box2", label = "Checkbox2", value = FALSE),
    actionButton('buttn', 'Validate'),
    verbatimTextOutput("out1"),
    verbatimTextOutput("out2")
  ),
  server = function(input, output) {
    observeEvent(input$buttn, {

      observeEvent(input$box1, {
        output$out1 <-  renderText({"Foo"})});

      observeEvent(input$box2, {
        output$out2 <-  renderText({"bar"})})

    })
  }
)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    请注意,将observeEventsreactives 放在其他observeEvents 中是不好的做法。见this slide and the two after it from a presentation by Joe Cheng

    一种可能的解决方案是使用shinyjs 包简单地显示或隐藏元素。下面给出了一个工作示例。

    另一种解决方案是使用reactiveVal 保存要显示的文本,并从您的观察者那里更新。

    希望这会有所帮助!


    解决方案 1

    library(shiny)
    library(shinyjs)    
    
    ui <- basicPage(
      checkboxInput("box1", label = "Checkbox1", value = FALSE),
      checkboxInput("box2", label = "Checkbox2", value = FALSE),
      actionButton('buttn', 'Validate'),
      shinyjs::hidden(div(id='div1', verbatimTextOutput("out1"))),
      shinyjs::hidden(div(id='div2', verbatimTextOutput("out2"))),
      useShinyjs()
    )
    
    server <- function(input, output) {
      observeEvent(input$buttn, {
        if(input$box1)
          shinyjs::show('div1')
        else
          shinyjs::hide('div1')
    
        if(input$box2)
          shinyjs::show('div2')
        else
          shinyjs::hide('div2')
      })
    
      output$out1 <-  renderText({"Foo"})
      output$out2 <-  renderText({"bar"})
    
    }
    
    shinyApp(ui,server)
    

    解决方案 2

    library(shiny)
    library(shinyjs)
    
    ui <- basicPage(
      checkboxInput("box1", label = "Checkbox1", value = FALSE),
      checkboxInput("box2", label = "Checkbox2", value = FALSE),
      actionButton('buttn', 'Validate'),
      verbatimTextOutput("out1"),
      verbatimTextOutput("out2")
    )
    
    server <- function(input, output) {
      text1 <- reactiveVal(NULL)
      text2 <- reactiveVal(NULL)
    
      observeEvent(input$buttn, {
        ifelse(input$box1,text1('Foo'),text1(NULL))
        ifelse(input$box2,text2('Bar'),text2(NULL))
      })
    
      output$out1 <-  renderText({text1()})
      output$out2 <-  renderText({text2()})
    
    }
    
    shinyApp(ui,server)
    


    【讨论】:

      【解决方案2】:

      您不需要额外的事件观察者。只需观察按钮单击并使用标准 R 条件逻辑根据复选框调整输出。

      shinyApp(
          ui = basicPage(
              checkboxInput("box1", label = "Checkbox1", value = FALSE),
              checkboxInput("box2", label = "Checkbox2", value = FALSE),
              actionButton('buttn', 'Validate'),
              verbatimTextOutput("out1"),
              verbatimTextOutput("out2")
          ),
          server = function(input, output) {
              observeEvent(input$buttn, {
                  if (input$box1) {
                      output$out1 <-  renderText({"Foo"})
                  }
                  if (!input$box1) {
                      output$out1 <-  renderText({NULL})
                  }
                  if (input$box2) {
                      output$out2 <-  renderText({"Bar"})
                  }
                  if (!input$box2) {
                      output$out2 <-  renderText({NULL})
                  }
              })
          }
      )
      

      【讨论】:

      • 尽管此解决方案有效,但我想指出以供将来参考,从 observer 内部设置 output 元素在 Shiny 中并不是一个好的做法。另请参阅我的回答中的演示文稿或 Joe Cheng 的评论 here
      • 我 100% 同意并认为您的解决方案#2 是最佳实践。我尝试构建尽可能接近 OP 描述的场景的解决方案。在额外的包/新数据结构和帮助人们摆脱困境之间始终保持平衡:)
      • 好吧,很高兴听到 ;) 我确实看到了在 OP 代码附近构建解决方案的意义,这使 OP 更容易看到他/她的代码哪里出错了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      • 2011-10-29
      相关资源
      最近更新 更多