如何在另一个模块中使用callModule? (我可以使用相同的ID吗?)

时间:2017-11-30 15:19:35

标签: r shiny

我试图在另一个模块(服务器端)内使用callModule。但是,使用callModule时,我需要提供id参数。我希望能够将提供给outerModule的相同ID传递给每个内部模块。

换句话说,有没有办法访问id一个模块是用模块中调用的?

library(shiny)

innerModule1 <- function(input, output, session, someReactiveInput){

  table <- reactive({
    table <- someCode(someReactiveInput())
  })

  return(table)

}

innerModule2 <- function(input, output, session, someOtherReactiveInput){

  table <- reactive({
    table <- someOtherCode(someOtherReactiveInput())
  })

  return(table)

}

outerModule <- function(input, output, session, someReactiveInput, someOtherReactiveInput){

  table <- reactive({

    table1 <- callModule(
      innerModule1,
      id = "hardcodedID",   # I want to use the same id as the one provided to outerModule
      someReactiveInput
    )

    table2 <- callModule(
      innerModule2,
      id = "hardcodedID",   # I want to use the same id as the one provided to outerModule
      someOtherReactiveInput
    )

    table <- someMoreCode(table1(), table2())

  })

  # More code follows here, but let's keep it simple for now

}

ui <- navbarPage( # Some inputs which are not relevant here I think )

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

  table_A <- callModule(
    outerModule,
    id = "A",
    someReactiveInput_A,
    someOtherReactiveInput_A
  )

  table_B <- callModule(
    outerModule,
    id = "B",
    someReactiveInput_B,
    someOtherReactiveInput_B
  )

  # More code

}

我知道另一种方法是将两个表作为outerModule的输入传递。但是,这需要我直接在服务器函数内部的两个内部模块上使用callModule。这会产生更多的代码重复(我必须做两次,每次id一次),并且会使我已经很长的服务器功能更长......

1 个答案:

答案 0 :(得分:2)

您可以使用ns函数获取模块内的ID:

session$ns("")

产生“ORIGINAL_ID-”。删除-会提供您想要的ID,即您正在寻找

sub("-", "", session$ns(""))

您的最小示例不可运行,请参阅下面的示例。

library(shiny)

innerModule1 <- function(input, output, session, someReactiveInput){

  table <- reactive({
    return(data.frame(col1 = someReactiveInput()))
  })

  return(table)

}

innerModule2 <- function(input, output, session, someOtherReactiveInput){

  table <- reactive({
    return(data.frame(col1 = someOtherReactiveInput()))
  })

  return(table)

}

outerModule <- function(input, output, session, someReactiveInput, someOtherReactiveInput){

  table <- reactive({

    table1 <- callModule(
      innerModule1,
      id = sub("-", "", session$ns("")),
      someReactiveInput
    )

    table2 <- callModule(
      innerModule2,
      id = sub("-", "", session$ns("")),
      someOtherReactiveInput
    )

    return(rbind(table1(), table2()))

  })

  return(table)

}

ui <- fluidPage(title="",
                 numericInput("inputA1", "Input 1", value =1),
                 numericInput("inputA2", "Input 2", value =2),
                 tableOutput("table_A"),
                 tableOutput("table_B"))

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

    table_A <- callModule(
      outerModule,
      id = "A",
      reactive({ input$inputA1 }),
      reactive({ input$inputA2 })
    )

    output$table_A <- renderTable({
      data.frame(a=table_A())
    })

    table_B <- callModule(
      outerModule,
      id = "B",
      reactive({ input$inputA1 }),
      reactive({ input$inputA2 })
    )

    output$table_B <- renderTable({
      data.frame(a=table_B())
    })

  }

  shinyApp(ui,server)