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” -> a1,a2,a3)。
- 点击按钮时,Control中的“B”被选中,Item中的“b1”和“b3”被选中
方法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 来指示控件更新时我们希望所选项目成为什么。然后我们在更新时使用这些值并重置反应值。
我正在构建一个应用程序,我需要将一些用户设置加载到各种输入中,包括一个动态 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” -> a1,a2,a3)。
- 点击按钮时,Control中的“B”被选中,Item中的“b1”和“b3”被选中
方法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 来指示控件更新时我们希望所选项目成为什么。然后我们在更新时使用这些值并重置反应值。