我有一个闪亮的应用程序,有两个selectInputs(L1和L2),观察者使用updateSelectInput根据L1的选择更新L2。我还有一个renderPlot输出,它取决于两个选择。我面临的问题是每当我更改L1时,renderPlot会被调用两次,一次使用旧值L2,一次使用新值(在updateSelectInput中设置)。我的代码如下:
ui.R
shinyUI(
fluidPage(
titlePanel("Nested Selects Problem"),
sidebarLayout(
sidebarPanel(
selectInput(
"L1",
label = "L1",
choices = c("red", "blue")
),
selectInput(
"L2",
label = "L2",
choices = ""
)
),
mainPanel(
plotOutput("plot")
)
)
)
)
server.R
shinyServer(
function(input,output,session) {
observe({
if (input$L1 == "red") {
choices <- c(1000000,2000000,3000000)
}
else {
choices <- c(10,20,30)
}
updateSelectInput(session,"L2",choices=choices,selected=choices[1])
})
output$plot <- renderPlot({
if (input$L2 != "") {
plot(runif(as.numeric(input$L2)),col=input$L1)
}
})
})
如何避免第一次调用renderPlot?在我看来,如果我可以安排在第一个renderPlot之前调用observe(),我会得到所需的效果。
感谢您的帮助。
答案 0 :(得分:1)
您可以在isolate
内的input$L1
来电中使用renderPlot
。通过这种方式,只有在updateSelectInput
发生更改时,更改才会从input$L1
来电传播:
library(shiny)
runApp(list(
ui = fluidPage(
titlePanel("Nested Selects Problem"),
sidebarLayout(
sidebarPanel(
selectInput("L1",label = "L1",choices = c("red", "blue")),
selectInput("L2",label = "L2",choices = "")
),
mainPanel(
plotOutput("plot")
)
)
)
, server = function(input,output,session) {
observe({
if (input$L1 == "red") {
choices <- c(100,200,300)
}
else {
choices <- c(10,20,30)
}
updateSelectInput(session,"L2",choices=choices,selected=choices[1])
})
output$plot <- renderPlot({
if (input$L2 != "") {
plot(runif(as.numeric(input$L2)),col=isolate(input$L1))
}
})
})
)
答案 1 :(得分:1)
那么,怎么样:
shinyServer(
function(input,output,session) {
L1_selected <- reactiveValues(triggered=-1)
observe({
if (input$L1 == "red") {
choices <- c(10, 100,200,300)
}
else {
choices <- c(10,20,30)
}
old_L2 <- isolate(input$L2)
updateSelectInput(session,"L2",choices=choices,selected=choices[1])
isolate(L1_selected$triggered <- L1_selected$triggered + as.numeric(old_L2 != choices[1]))
})
output$plot <- renderPlot({
if (input$L2 != "") {
if (isolate(L1_selected$triggered)) {
isolate(L1_selected$triggered <- L1_selected$triggered - 1)
return()
} else {
plot(runif(as.numeric(input$L2)),col=input$L1)
}
}
})
})