R闪亮的反应优先级

R Shiny reactive priority

我正在构建一个应用程序,我需要将一些用户设置加载到各种输入中,包括一个动态 selectInput,它的值取决于另一个 selectInput。我 运行 遇到一个问题,我想更新的动态 selectInput 立即被其他更新事件覆盖。下面的代码应该更好地解释它

### Approach A ###
{
    ui <- fluidPage(
        selectInput("controlSelect", "Control", choices = c("A", "B","C"), multiple = FALSE),
        uiOutput("itemUI"),
        actionButton("button", "Button")
    )
    
    server <- function(input, output, session) {
        output$itemUI <- renderUI({
            print("rendering itemUI and itemSelect")
            itemToShow <- switch(input$controlSelect,
                                             "A" = c("a1", "a2", "a3"),
                                             "B" = c("b1", "b2", "b3"),
                                             "C" = c("c1", "c2", "c3")
            )

            result <- selectInput("itemSelect", "Items", choices = itemToShow, multiple = TRUE)

            return(result)
        })

        observeEvent(input$button, {
            print("observed button so run updates")
            updateSelectInput(session, "controlSelect", selected = "B")
            updateSelectInput(session, "itemSelect", selected = c("b1", "b3"))
        })
        
    }
    
    # Run the application
    shinyApp(ui = ui, server = server)
}

### Approach B ###
{
ui <- fluidPage(
    selectInput("controlSelect", "Control", choices = c("A", "B","C"), multiple = FALSE),
    selectInput("itemSelect", "items", choices = c("a1", "a2", "a3"), multiple = TRUE),
    actionButton("button", "Button")
)

server <- function(input, output, session) {

    itemsRV <- reactiveValues(items ="")
    
    observeEvent(itemsRV$items, {
        print("updating itemSelect with itemsRV")
        updateSelectInput(session, "itemSelect", selected = itemsRV$items)
    }, priority = 1)
    
    observeEvent(input$controlSelect, {
        
        itemToShow <- switch(input$controlSelect,
                                                 "A" = c("a1", "a2", "a3"),
                                                 "B" = c("b1", "b2", "b3"),
                                                 "C" = c("c1", "c2", "c3")
        )
        print("observed controlSelect so update itemSelect")
        updateSelectInput(session, "itemSelect", choices = itemToShow)
    }, priority = 10)
    
    observeEvent(input$button, {
        print("----------button clicked-----------------")
        
        print("updating itemsRV")
        itemsRV$items <- c("b1", "b3")
        
        print("updating controlSelect")
        updateSelectInput(session, "controlSelect", selected = "B")
        
    }, priority = 10)
    
}

# Run the application
shinyApp(ui = ui, server = server)
}

期望的行为:

方法A是我写的第一个版本。它不起作用,但它只是展示了我试图实现的目标。如果在单击按钮之前已经在 Control 中选择了“B”,它确实可以工作。不管它是不够好。 方法 B 是我试图弄乱优先选项的一个版本。还是不行

我觉得问题不仅仅是反应的优先级,还有事件发射的优先级。希望有人能提供帮助。谢谢!

获得该行为的方法是方法 B 的变体。但是我们使用不同的反应值来设置项目的当前值。例如

ui <- fluidPage(
  selectInput("controlSelect", "Control", choices = c("A", "B","C"), multiple = FALSE),
  selectInput("itemSelect", "Items", choices=character(), multiple=TRUE),
  actionButton("button", "Button")
)

server <- function(input, output, session) {
  setItemValues <- reactiveVal(character())
  
  observeEvent(input$controlSelect, {
    itemToShow <- switch(input$controlSelect,
                         "A" = c("a1", "a2", "a3"),
                         "B" = c("b1", "b2", "b3"),
                         "C" = c("c1", "c2", "c3")
    )
    updateSelectInput(session, "itemSelect", 
                      choices = itemToShow, selected = setItemValues())
    setItemValues(character())
  })
  
  observeEvent(input$button, {
    print("observed button so run updates")
    updateSelectInput(session, "controlSelect", selected = "B")
    setItemValues(c("b1", "b3"))
  })
}

# Run the application
shinyApp(ui = ui, server = server)

由于我们依靠 input$controlSelect 更改来更新下拉列表中的项目,因此我们需要先更新这些项目,然后才能选择所选值。因此,在单击按钮时,我们会触发控件的更改,但随后只需设置一个 reactiveValue 来指示控件更新时我们希望所选项目成为什么。然后我们在更新时使用这些值并重置反应值。