[英]How does one isolate an input from another input in the same call to shiny::renderUI?
我有很多输入都存在于使用renderUI
在服务器端创建的同一个conditionalPanel
中。 我不能将其移至用户界面,因为某些部分使用了反应对象。
我想做的是让一个输入确定另一个输入的默认设置。 但是,由于这两者都存在于对renderUI
的同一调用中,因此会创建一个循环依赖项,这使我无法选择除前一个输入的默认选项以外的任何选项。 考虑以下示例app.R
文件:
library(shiny)
key <- c("a" = 1, "b" = 2, "c" = 3, "d" = 4)
ui <- fluidPage(
uiOutput("inputs")
)
server <- function(input, output) {
output$inputs <- renderUI(
tagList(
selectInput("input1", "Input 1:", letters[1:4]),
textInput("input2", "Input 2:", rval())
)
)
rval <- reactive(key[input$input1])
}
shinyApp(ui = ui, server = server)
我在全局环境中定义key
(在应用程序中,是从全局中的.yaml文件读取的),然后uiOutput
向用户显示所有输入。 我们可以看到, input2
的默认值取决于为input1
选择的内容。 发生的情况是input1
触发rval()
的更改,而后者又触发input2
的更改。 还行吧。 但是,由于input1
和input2
是在renderUI
的同一调用中renderUI
,因此input1
依赖于自身,因此只要用户在下拉菜单中选择另一个选项, input1
就会重置为默认值。
再次,我这样编码,因为这两个输入存在于我正在使用的实际应用程序的同一conditionalPanel
中(尽管在本工作示例中不是)。
我试着用isolate()
包围selectInput(...)
isolate()
,但这不起作用。
如何将两个输入保留在相同的renderUI
但允许用户更改input1
而不依赖于自身和重置?
您可以使用observeEvent(iunputs$input1, ...)
和updateTextinput
来使input2
保持最新。 使用此方法的优点是不必重新渲染UI。
library(shiny)
key <- c("a" = 1, "b" = 2, "c" = 3, "d" = 4)
ui <- fluidPage(
uiOutput("inputs")
)
server <- function(input, output, session) {
output$inputs <- renderUI({
tagList(
selectInput("input1", "Input 1:", letters[1:4]),
textInput("input2", "Input 2:", "placeholder")
)
})
observeEvent(input$input1, {
mapped_input <- key[[req(input$input1)]]
updateTextInput(session, "input2", value = mapped_input)
})
}
shinyApp(ui = ui, server = server)
req
确保只有在output$inputs
已经呈现的情况下才会调用updateTextInput
。
我意识到有usecases其中updateXXX
功能是不够的,呈现动态输入。 在这种情况下,最好在单独的renderUI
语句中生成UI,因此不再需要循环性。
注意:我看不到conditionalPanel
如何使必须使用renderUI
。 如果您正在寻找在代码中使用抽象的方法,请改用Shiny Modules 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.