我创建了一个简单的项目,我从一个模块(选择器)中的列表中生成选择输入,该模块返回输入列表。我有另一个模块(查看器),它接受从选择器模块返回的输入并生成与 Count selectInput 值对应的许多 textOuputs,它们的文本对应于 Colors selectInput 值。问题是生成的输入无法识别,因此不会被要返回的输入列表选择。我能让它们被识别的唯一方法是,如果我对我不想做的 selectInputs 进行硬编码(我已将它们添加到 selectorUI 中作为参考以供参考)。
用户界面
library(shiny)
HOME_DIR<-getwd()
source(file.path(HOME_DIR,'subUI.R'),local=TRUE)
shinyUI(fluidPage(
titlePanel("Sample App"),
sidebarLayout(
sidebarPanel(
selectorUI("selectorModl")
),
mainPanel(
viewerUI("viewerModl")
)
)))
服务器
library(shiny)
HOME_DIR<-getwd()
source(file.path(HOME_DIR,'subUI.R'),local=TRUE)
shinyServer(function(input, output) {
selection <- list("count" = c(1,2,3,4,5), "colors" = c("blue", "green","red"))
inputValues<-reactive(callModule(selector,"selectorModl", selection))
observeEvent(inputValues(),{
if(length(inputValues()))
callModule(viewer, "viewerModl", inputValues())
})
})
子界面
#----------selector subUI
selectorUI<-function(id){
ns <- NS(id)
tagList(
htmlOutput(ns("selectorPane"))
# selectInput(ns("count"), label = "count", choices = "", multiple = F)
# ,selectInput(ns("colors"), label = "colors",choices = "", multiple = F)
)
}
selector<-function(input, output, session,selection){
output$selectorPane <- renderUI({
lapply(1:length(selection), function(selIdx){
selName <- names(selection)[selIdx]
selChoices<-selection[[selName]]
selectInput(inputId = selName, label = selName, choices = selChoices, multiple = F)
})
})
observe({
print(names(input))
if(!is.null(input[["count"]])){
if(input[["count"]]==""){
lapply(1:length(selection), function(selIdx){
selName <- names(selection)[selIdx]
selChoices<-selection[[selName]]
updateSelectInput(session, inputId = selName, choices = selChoices)
})
}
}
})
return(input)
}
#----------viewer subUI
viewerUI<-function(id){
ns <- NS(id)
uiOutput(ns("viewerPane"))
}
viewer<-function(input, output, session, inputValues){
output$viewerPane <- renderUI({
if(length(inputValues) > 0)
if(!is.null(inputValues[["count"]]) && inputValues[["count"]] != "" && !is.null(inputValues[["colors"]]))
lapply(1:inputValues[["count"]], function(idx){
textInput(paste("text",idx, sep = "_"), label = "", value = inputValues[["colors"]])
})
})
}
这是我想要实现的屏幕截图。任何帮助,将不胜感激。谢谢!
我已将此作为单独的答案包含在内,以避免混淆代码。
这是一个使用模块和动态 ui 的工作版本。注意ns <- session$ns
模块内的使用。还要小心反应性函数。我通常将变量命名为 rfVariableName 以提醒我它是一个反应函数而不仅仅是一个普通变量。
library(shiny)
# selctor Module ---------------
selectorUI <- function(id) {
ns <- NS(id)
uiOutput(ns("selectorPane"))
}
selector <- function(input, output, session, selection) {
output$selectorPane <- renderUI({
ns <- session$ns
tagList(
lapply(1:length(selection), function(selIdx){
selName <- names(selection)[selIdx]
selChoices <- selection[[selName]]
selectInput(inputId = ns(selName), label = selName, choices = selChoices, multiple = F)
})
)
})
allInputs <- reactive({
l <- lapply(1:length(selection), function(getid) {
selName <- names(selection)[getid]
input[[selName]]
})
names(l) <- names(selection)
l
})
return(allInputs)
}
# Viewer Module ---------------
viewerUI <- function(id) {
ns <- NS(id)
uiOutput(ns("viewerPane"))
}
viewer <- function(input, output, session, inputValues) {
output$viewerPane <- renderUI({
ns <- session$ns
if (length(inputValues()) > 0) {
if (!is.null(inputValues()[["count"]])) {
if (inputValues()[["count"]] > 0) {
tagList(
lapply(1:inputValues()[["count"]], function(idx){
textInput(ns(paste("text",idx, sep = "_")), label = "", value = inputValues()[["colors"]])
})
)
}
}
}
})
}
# Main UI --------------
ui <- shinyUI(fluidPage(
titlePanel("Sample App"),
sidebarLayout(
sidebarPanel(
selectorUI("selectorModl")
),
mainPanel(
viewerUI("viewerModl")
)
)))
# Server
server <- function(input, output, session) {
selection <- list("count" = c(1,2,3,4,5), "colors" = c("blue", "green","red"))
inputValues <- callModule(selector,"selectorModl", selection = selection)
observeEvent(inputValues(),{
if (length(inputValues()) > 0) {
callModule(viewer, "viewerModl", inputValues = inputValues)
}
})
}
shiny::shinyApp(ui, server)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句