R Shiny:如何使用主服务器功能中的条件来调用不同的模块UI /服务器功能?

时间:2017-10-10 06:16:38

标签: r shiny

我试图在主服务器函数中使用if / then构造来根据用户输入确定调用哪两个模块中的哪个模块。一种选择使用添加/删除操作按钮模块来调用另一个模块,另一种选择使用添加/删除按钮模块调用不同的模块。使用添加/删除模块调用模块很容易,因为我通过UI调用作为添加/删除按钮模块调用中的参数之一,但我不确定如何在服务器中正确插入UI() callModule()之后的函数。所以在我的例子中(就像我想的那样简单),UI以textInput()框开头,默认为1.我有一个"第一个"模块,它只是将userInput()数据添加到selectInput()框中的字母a,b,c d。 "第二"模块前置"不是1"到selectInput()框中的a,b,c,d。我使用observeEvent({}),如果用户什么都不做(textInput()保持为1),那么"首先"模块被调用。如果用户将textInput()更改为除默认值1以外的任何内容,则" second"模块被调用。我不清楚的是如何调用第二个模块的UI。我有一个uiOutput(" dummy")作为ui()函数的占位符。但是,我的例子不能像上面描述的那样工作,因为它没有成功地调用" second"模块,如果用户更改testInput()默认值。代码如下,谢谢!

library(shiny)

firstUI <- function(id) { uiOutput(NS(id, "first")) }

firstServer <- function(input, output, session, a) {
    ns = session$ns

    output$first <- renderUI({
        selectInput(ns("select"), h4("Select"), paste0(isolate(a()), letters[1:4]))
    })

    return(reactive({ c(paste0(input$select), paste0(input$select)) }))
}
removeFirstUI <- function(id) {
    removeUI(selector = paste0('#', NS(id, "first")))
}

secondUI <- function(id) { uiOutput(NS(id, "second")) }

secondServer <- function(input, output, session, a) {
    ns = session$ns

    output$second <- renderUI({
        selectInput(ns("select"), h4("Select"), paste0("Not 1", letters[1:4]))
    })

    return(reactive({ c(paste0(input$select), paste0(input$select)) }))
}

removeSecondUI <- function(id) {
    removeUI(selector = paste0('#', NS(id, "second")))
}

addRmBtnUI <- function(id) {
    ns <- NS(id)

    tags$div(
    actionButton(inputId = ns('insertParamBtn'), label = "Add"),
    actionButton(ns('removeParamBtn'), label = "Remove"),
    hr(),
    tags$div(id = ns('placeholder'))
  )
}

addRmBtnServer <- function(input, output, session, moduleToReplicate, ...) {
    ns = session$ns

    params <- reactiveValues(btn = 0, a = list())

    observeEvent(input$insertParamBtn, {
        params$btn <- params$btn + 1

        params$a[[params$btn]] <- callModule(moduleToReplicate$server, id = params$btn, ...)
        insertUI(
      selector = paste0('#', ns('placeholder')),
      ui = moduleToReplicate$ui(ns(params$btn))
    )
    })

    observeEvent(input$removeParamBtn, {
        moduleToReplicate$remover(ns(params$btn))
        params$btn <- params$btn - 1
    })

    return(params)
}

ui <- fluidPage(
  addRmBtnUI("addRm"),
  textInput("a", label = "a", value = 1, width = '150px'),
  verbatimTextOutput("text", placeholder = TRUE),
  uiOutput("dummy")
)

server <- function(input, output, session) {

    a <- reactive({ input$a })
    comp <- reactiveValues()
    observeEvent(a(), {
        if (input$a == 1) {
            comp <- callModule(
            addRmBtnServer, id = "addRm",
            moduleToReplicate = list(
            ui = firstUI,
            server = firstServer,
            remover = removeFirstUI
            ),
            a = a
            )
        } else {
            comp <- callModule(
            secondServer, id = 0,
            a = a
            )
        }
    }, ignoreNULL = TRUE)

    output$text <- renderPrint({
        if (!(is.null(comp$btn))) {
            if (comp$btn > 0) {
            paste(
            comp$a[[comp$btn]](),
            sep = "     "
            )
            }
            } else { paste0("") }
    })

}

shinyApp(ui = ui, server = server)

0 个答案:

没有答案