朋友, 由于某种原因,我不得不以动态方式呈现ui(不同用户使用不同的GUI),并且遇到了无论如何都无法克服的问题。尝试隔离,反应性,更新,一切都使我失败。也许您对如何解决它有一些想法(或者您可能认为将其引入渲染ui绝对是愚蠢的-希望不是因为它已经是庞大的应用程序了)。所以首先是一个没有任何问题的示例(问题的简化表示,而不是真正的应用程序)
node
没有任何小问题,可以更新顶部列表,缩小底部列表的范围 但是在渲染ui的情况下,更改第一个列表会导致整个ui的更新,因此将选择中的顶层列表更改为第一个位置,从而否定了您的选择
library(shiny)
library(magrittr)
library(dplyr)
ui <- fluidPage(
selectInput("cyl","cyl",unique(mtcars$cyl)),
selectInput("mpg","mpg","")
)
server <- function(input, output, session) {
mpg<- reactive({unique(mtcars%>%dplyr::filter(cyl==input$cyl)%>%select(mpg))})
observeEvent(input$cyl,{updateSelectInput(session,"mpg", choices = mpg())})
}
shinyApp(ui = ui, server = server)
如何防止整个UI重建?在这个简单的示例中,它被简化为2个输入,但是在应用程序中,它是一个较大的传单地图,应通过更改为几个输入中的任何一个来更新-很难存储先前选择的值并在刷新后重新选择它们,但是也许这是唯一的方法
答案 0 :(得分:0)
在第二种情况下,由于ui <- uiOutput("myUI")
,您最终得到了循环反应性逻辑。基本上,每当更新UI时,都会重新生成UI。在这种情况下,renderUI
的使用方法如下-
library(shiny)
library(magrittr)
library(dplyr)
ui <- fluidPage(
selectInput("cyl","cyl",unique(mtcars$cyl)),
uiOutput("select_mpg")
)
server <- function(input, output, session) {
mpg <- reactive({
req(input$cyl)
m <- mtcars %>% dplyr::filter(cyl == input$cyl)
unique(m$mpg)
})
output$select_mpg <- renderUI({
selectInput("mpg","mpg",mpg())
})
}
shinyApp(ui = ui, server = server)
请注意,我还做了一些其他更改以使应用程序正常运行并使代码更具可读性。
答案 1 :(得分:0)
很抱歉打扰您,但这太简单了,应该立即发现它 我可以像这样在ui内部渲染ui
library(shiny)
library(magrittr)
library(dplyr)
ui <- uiOutput("myUI")
server <- function(input, output, session) {
output$myUI<-renderUI({
fluidPage(
selectInput("cyl","cyl",unique(mtcars$cyl)),
uiOutput("xmpg")
)
})
output$xmpg<-renderUI({selectInput("mpg","mpg",mpg())})
mpg<- reactive({
if(!is.null(input$cyl))
unique(mtcars%>%dplyr::filter(cyl==input$cyl)%>%select(mpg))
})
}
shinyApp(ui = ui, server = server)
那么任何调用都不会重新渲染顶级用户界面,而只是重新渲染有问题的用户界面