insertUI 根据先前的值创建无限输入

问题描述 投票:0回答:1

我正在尝试使用

insertUI
renderUI
为用户创建无限的潜在输入。据我了解,这可以通过
actionButton
轻松完成,这是使用
actionButton
的示例:在R闪亮模块中使用actionButton + insertUI来创建多个输入但是,我还没有看到open中的用法字段输入,例如文本/数字。当我尝试基于文本/数字输入创建实例时,我似乎总是使用
insertUI
renderUI
创建重复项。

  • 我的代码将使用 UI 模块来创建
    numericInput
  • 然后我使用服务器的第二个模块来创建
    observeEvent
    检查输入中的数字。如果该号码存在并且 超过10,那么它将
    insertUI
    使用UI模块。
  • 在服务器中,我使用
    observe
    来检查输入数量,因此 它将知道要创建多少个服务器模块。这是哪里 我怀疑问题所在,因为它往往会创建 UI 的多个实例 模块。之前有人告诉我,在
    observeEvent
    中包含
    observe
    是不好的做法,尽管我不知道还有什么其他方法可以实现这一点。

如何只插入单个 UI,而不是多个 UI?

代码:

library(shiny)

#Modules and functions########################
#UI module to create a numeric input
numericModule <- function(id) { 
  numericInput(inputId = NS(id, "Numeric"), 
               label = paste0(id), 
               value = NA)  
}

#This is my servermodule. If number is above 10, insertUI
numericObserver <- function(id) {
  
  moduleServer(id, function(input, output, session) {
    #For the Numeric input, observeEvent
    observeEvent(input$Numeric, {
      
      #If value exists and is over 10...
      if(!any(is.null(input$Numeric),
             is.na(input$Numeric),
             input$Numeric < 10)) {
        
        #Insert new input after
        insertUI(selector = paste0("#", NS(id, "Numeric")),
                 where = "afterEnd",
                 ui = numericModule(id+1))
        
      }
    })
    
  })
}


#UI ########################

ui <- fluidPage(
  numericModule(1)
)

#SERVER ##########################

server <- function(input, output, session) {
  
  #Observe the inputs. For each input, create a new servermodule
  #*This is where I believe the problem lies***
  observe({
    
    lapply(1:length(names(input)), function(x) {
      
      numericObserver(x)
      
    })
    
  })
  
}

#RUN SHINY#################
shinyApp(ui, server)
r shiny
1个回答
0
投票

这是我认为你想做的事情的解决方案。

library(shiny)

numericUI <- function(id) {
  ns <- NS(id)
  numericInput(
    inputId = ns("numeric"),
    label = paste0(id),
    value = NA
  )
}

numericServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    observe({
      print(paste0("input ", id, ": ", input$numeric))

      if (isTruthy(input$numeric) && input$numeric > 9) {
        insertUI(
          "#input-container",
          "beforeEnd",
          numericUI(id + 1)
        )
      }
    })
  })
}

ui <- fluidPage(
  div(
    id = "input-container",
    numericUI(1)
  )
)


server <- function(input, output, session) {
  observe({
    existing_inputs   <- names(input)
    input_numbers     <- str_extract(existing_inputs, "\\d+") |> as.numeric()
    newer_input_index <- max(input_numbers)
    
    numericServer(newer_input_index)
  })
  
}

shinyApp(ui, server)
© www.soinside.com 2019 - 2024. All rights reserved.