Update SelectInput without trigger reactive?

2019-08-02 20:25发布

问题:

I am new to shiny but kind of like it. Now I have an interesting question in needing of help. I have a database can be queried by either indexA and indexB, but not both. That is if I use selectInput to retrieve data from one index(for example, indexA), I have to set another index(in this case, indexB) to default value(B0), and vise versa. The output widget is depends on both selectInput. Hence, if I interact one selectInput to query data, I need to update another selectInput, which will cause the reactive of selectInput will be called twice. Is there anyway to execute updateSelectInput without triggering reactive()? The simplified code is below for your reference:

library(shiny)

indexA = c('A0', 'A1', 'A2', 'A3', 'A4', 'A5')
indexB = c('B0', 'B1', 'B2', 'B3', 'B4', 'B5')

ui <- fluidPage(
    selectInput('SelA', 'IndexA', choices = indexA, selected = NULL),
    selectInput('SelB', 'IndexB', choices = indexB, selected = NULL), 
    verbatimTextOutput('textout')
)

server <- function(input, output, session) {
    GetIndexA <- reactive({
        updateSelectInput(session, "SelB", choices = indexB, selected = NULL)
        ta <- input$SelA
    })

    GetIndexB <- reactive({
        updateSelectInput(session, "SelA", choices = indexA, selected = NULL)
        tb <- input$SelB
    })

    output$textout <- renderText({
        textA = GetIndexA()
        textB = GetIndexB()
        paste("IndexA=", textA, " IndexB=", textB, "\n")
    })
}

shinyApp(ui, server) 

回答1:

Here is a simple way to do it by updating only when selected value is not the default value:

server <- function(input, output, session) {
  GetIndexA <- reactive({
    ta <- input$SelA
    if(ta!=indexA[1])
      updateSelectInput(session, "SelB", choices = indexB, selected = NULL)
    ta
  })

  GetIndexB <- reactive({
    tb <- input$SelB
    if(tb!=indexB[1])
      updateSelectInput(session, "SelA", choices = indexA, selected = NULL)
    tb
  })

  output$textout <- renderText({
    textA = GetIndexA()
    textB = GetIndexB()
    paste("IndexA=", textA, " IndexB=", textB, "\n")
  })
}