2017-10-05 18 views
1

我有一个简单的玩具示例,使用add/removeBtn模块来添加和删除“第一个”模块的UI。我需要跟踪添加/删除被点击的次数。如果我不使用模块,这很容易,但我试图在嵌套模块的上下文中执行此操作。代码在下面,但基本上,我似乎无法访问主服务器函数中addRmBtnServer()的返回值。我相信这是一个简单的修复,但我已经尝试了很多方法,但似乎无法访问我对addRmBtnServer()的调用结果。谢谢!R Shiny:如何将闪亮模块的反应值返回到主服务器功能?

library(shiny) 

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

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

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

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

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) 

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

     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$btn) 
} 

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

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

    pars <- callModule(
    addRmBtnServer, id = "addRm", 
    moduleToReplicate = list(
     ui = firstUI, 
     server = firstServer, 
     remover = removeFirstUI 
     ), 
    ) 

    output$view <- renderText({ pars() }) 

} 

shinyApp(ui = ui, server = server) 
+0

您可以使用服务器功能的返回值传递观察值(输入)。首先你从'fisrtServer'传递给'addRmBtnServer',然后从'addRmBtnServer'传递到'server'上下文。看到我的答案[这里](https://stackoverflow.com/questions/46555355/passing-data-within-shiny-modules-from-module-1-to-module-2/46555851#46555851) –

回答

1

如评论所述,您可以将值作为返回值传递给相应的服务器功能。下面有一个工作示例。我遗漏了firstUI,firstServerremoveFirstUI实现,因为它们与您的问题无关。

library(shiny) 

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) 

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

    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(reactive({params$btn})) 
} 

ui <- fluidPage(
    addRmBtnUI("addRm"), 
    verbatimTextOutput("view", placeholder = TRUE) 
) 

server <- function(input, output, session) { 
    a <- reactive({input$a}) 

    pars <- callModule(
    addRmBtnServer, id = "addRm", 
    moduleToReplicate = list(
     ui = function(...){}, 
     server = function(...){}, 
     remover = function(...){} 
    ) 
) 
    output$view <- renderText({ pars() }) 
} 

shinyApp(ui = ui, server = server)