【问题标题】:problem in adding several shiny modules using insertUI使用 insertUI 添加几个闪亮模块的问题
【发布时间】:2020-07-07 20:44:46
【问题描述】:

我构建了一个闪亮的应用程序,它需要根据一些我只会实时知道的参数动态添加 UI 片段。我对自己的需求进行了简单的重构,遇到了我在下面描述的问题

所以在我的示例中,我有一个名为 mblock 的模块。为了这个例子,它只显示一个文本。要显示的实际文本是在运行时决定的,因此文本(以及块)的数量将在运行时决定

对于特定示例,我将文本设置为包含所有要显示的文本的固定向量,但实际上它将被计算为反应对象。代码如下:

library(shiny)

#block module
mblockUI = function(id) {
    ns = NS(id)
    fluidRow(
        textOutput(ns("text"))
    )
}

mblock = function(input,output,session,actual_text) {
    output$text = renderText({actual_text})
}


# Define the main ui 
ui <- fluidPage(
    uiOutput("all_blocks"),
    actionButton("submit","submit")
)

# Define server logic
server <- function(input, output) {
    texts = c("aaaa","bbbb","cccc") #this is a sample vector of texts to be shown in blocks

    output$all_blocks = renderUI({
        for(i in 1:length(texts)) {
            mname = paste0("block",i)  #block name to be created (the name of the module)
            #print(mname)
            insertUI("#submit","beforeBegin",mblockUI(mname))  #adding the ui
            #now adding the server side of each block
            #also passing the text to be shown
            callModule(mblock,mname,texts[i])     
        }
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

问题是所有块都显示相同的文本(最后一个)。我不明白为什么

任何想法如何修复代码?我想念什么 (闪亮版 1.4.0)

【问题讨论】:

    标签: r shiny shinymodules


    【解决方案1】:

    首先,insertUI 能够“独立”工作,不需要renderUI。您可以将其放在 observe 环境中。但是,请注意 insertUI 的输出,因为它是持久的,如该函数的文档中所述:

    与 renderUI() 不同,使用 insertUI() 生成的 UI 是持久的:一旦创建,它就会一直保留在那里,直到被 removeUI() 删除。对 insertUI() 的每次新调用都会创建更多的 UI 对象,除了已经存在的对象(都相互独立)。要更新 UI 的一部分(例如:输入对象),您必须使用适当的渲染函数或自定义的反应函数。

    我不知道为什么,但 for 循环不起作用(如您的示例所示),而 lapply 起作用(例如,请参见 this answer)。

    这是您的示例,其中包含这些更正:

    library(shiny)
    
    #block module
    mblockUI = function(id) {
      ns = NS(id)
      fluidRow(
        textOutput(ns("text"))
      )
    }
    
    mblock = function(input,output,session,actual_text) {
      output$text = renderText({actual_text})
    }
    
    
    # Define the main ui 
    ui <- fluidPage(
      actionButton("submit","submit")
    )
    
    # Define server logic
    server <- function(input, output) {
      texts = c("aaaa","bbbb","cccc") #this is a sample vector of texts to be shown in blocks
      
      observe({
        lapply(1:length(texts), function(i) {
          mname = paste0("block",i)  #block name to be created (the name of the module)
          #print(mname)
          insertUI("#submit","beforeBegin",mblockUI(mname))  #adding the ui
          #now adding the server side of each block
          #also passing the text to be shown
          callModule(mblock,mname,texts[i])     
        })
      })
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    【讨论】:

      猜你喜欢
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 2021-08-14
      • 2021-11-06
      • 2021-11-23
      • 2019-01-18
      • 2016-07-02
      相关资源
      最近更新 更多