R闪亮模块-模块返回多个reactiveVals到主服务器

hrirmatl  于 2023-05-20  发布在  React
关注(0)|答案(1)|浏览(118)

我在main serverserver module之间的通信有问题。我想从模块返回当前reactiveVals,然后在主应用程序中使用它们。我创建了一个基本的应用程序,它显示了我的问题。模块包含2个按钮和2个reactiveVals,每个按钮包含相应按钮的点击次数。在主服务器中,我想知道哪个值发生了变化,并通过一些操作(在示例中,返回文本中的变化)对此变化做出React。不幸的是,下面的代码只在模块启动时返回模块的值,那么,如果模块内部有我们感兴趣的更改,我不会得到通知。
我应该如何修改下面的代码才能得到我感兴趣的效果?

library(shiny)

moduleUI <- function(id){
  ns <- NS(id)
  wellPanel(
    fluidRow(
      column(3, uiOutput(ns("button1"))),
      column(3, uiOutput(ns("button2")))
    )
  )
}

moduleServer <- function(input, output, session){
  rv_button1 <- reactiveVal(0)
  rv_button2 <- reactiveVal(0)
  
  observeEvent(input$button1, {
    rv_button1(rv_button1()+1)
    print(rv_button1())
  })
  observeEvent(input$button2, {
    rv_button2(rv_button2()+1)
    print(rv_button2())
    
  })
  
  output$button1 <- renderUI({
    actionButton("button1", label = "button 1")
  })
  output$button2 <- renderUI({
    actionButton("button2", label = "button 2")
  })
  
  return(
    list(
      button1 = rv_button1,
      button2 = rv_button2
    )
  )
}

ui <- fluidPage(
  moduleUI("moduleId"),
  fluidRow(uiOutput("text"))
)

server <- function(input, output, session) {
  rv_module <- reactiveVal(
    list(
      button1 = 0, 
      button2 = 0
    )
  )
  rv_text <- reactiveVal("")
  
  rv_module <- callModule(moduleServer, "moduleId")

  observeEvent(rv_module$button1, {
    rv_text("Button 1 was clicked")
  })
  observeEvent(rv_module$button2, {
    rv_text("Button 2 was clicked")
  })
  
  output$text <- renderUI({
    HTML(rv_text())
  })
}

runApp(shinyApp(ui, server))
s3fp2yjn

s3fp2yjn1#

先做几件事:

  • 你需要在一个模块中添加ns()到你的inputId,即使它是服务器端。
  • 不能将两个输出命名为相同:button1对于buttonuiOutput,它不会工作。

然后,要在服务器和模块之间,或者在几个模块之间进行通信,最简单的方法是传递一个reactiveValues作为模块的参数。

library(shiny)

moduleUI <- function(id){
  ns <- NS(id)
    column(3, uiOutput(ns("uibutton1"))),
    column(3, uiOutput(ns("uibutton2")))
}

moduleServer <- function(input, output, session, rv){
  ns <- session$ns # don't forget ns in server side module
  observeEvent(input$button1, {
    rv$btn1 <- rv$btn1 +1
  })
  observeEvent(input$button2, {
    rv$btn2 <- rv$btn2 +1
  })
  
  # do not use the same outputId 
  output$uibutton1 <- renderUI({
    actionButton(ns("button1"), label = "button 1") # use ns()
  })
  output$uibutton2 <- renderUI({
    actionButton(ns("button2"), label = "button 2")
  })
}

ui <- fluidPage(
  moduleUI("moduleId"),
  uiOutput("text")
)

server <- function(input, output, session) {
  # Initialise a reactiveValues
  rv_module <- reactiveValues(btn1 = 0, btn2 = 0)

  callModule(moduleServer, "moduleId", rv = rv_module)
  
  output$text <- renderUI({
    paste("btn1 : ",rv_module$btn1, " | btn2 : ", rv_module$btn2)
  })
}

runApp(shinyApp(ui, server))

相关问题