गतिशील रूप से बनाए गए चमकदार मॉड्यूल के लौटे हुए मूल्यों तक पहुँचें

Aug 18 2020

मैं एक चमकदार ऐप बनाने के लिए देख रहा हूं जो गतिशील रूप से मॉड्यूल (कॉलमॉड्यूल के माध्यम से) बनाता है जो एक सरल रूप देता है। मेरे पास इस पर 2 ढीले छोर हैं जो मुझे कृपया कुछ मार्गदर्शन की सराहना करेंगे।

सबसे पहले, जब उपयोगकर्ता के लिए (एक बटन क्लिक के माध्यम से) कई फॉर्म लाए जाते हैं, तो पहले से रेंडर किए गए फॉर्म के मान डिफ़ॉल्ट पर वापस आ जाते हैं। मैं इस व्यवहार को कैसे रोकूं ताकि उपयोगकर्ता के चयन पर मूल्य बने रहें?

और 2, मैं चयन से मूल्यों को 'सभी' तक कैसे पहुँचा और पेश करूँ जो एक तालिका में दिखाया जा सके? मैंने एक सरल उदाहरण रखा है नीचे दिए गए अवलोकन का उपयोग करके; मैं भी घटना के साथ एक बदलाव की कोशिश की। हालांकि मैं सिर्फ callmodule outputs का उपयोग करने के लिए प्रतीत नहीं कर सकते हैं।

अग्रिम में Thnx!

library(shiny)
library(stringr)


gen_r_8_formUI <- function(id){
  
  ns <- NS(id)
  
  tagList(fluidRow(column(width = 4, selectInput(ns("slt_forename"), 'forename', choices = unique(c("john", "paul", "george", "ringo")))),
          column(width = 4, selectInput(ns("slt_surname") , 'surname' , choices = unique(c("lennon", "mccartney", "harrison", "starr"))))))
}

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

  select_values <- reactiveValues(forename = NULL, surname = NULL)  
  observeEvent(input$slt_forename,{select_values$forename <- input$slt_forename}) observeEvent(input$slt_surname, {select_values$surname <- input$slt_surname})
  select_values_all <- reactive({tibble(forename  = select_values$forename, surname = select_values$surname)})
  
  return(list(select_values_all = reactive({select_values_all()})))
}


ui <- fluidPage(
  column(width = 2, actionButton("btn_gen_r_8_form", "GEN R 8 a FORM")),
  column(width = 6, uiOutput("all_ui_forms")),
  column(width = 4, tableOutput("all_form_values_table")))

server <- function(input, output) {
  
  rctv_uis                     <- reactiveValues(all_ui          = list())
  gen_forms                    <- reactiveValues(all_form_values = list())
  output$all_ui_forms <- renderUI({tagList(rctv_uis$all_ui)})
  output$all_form_values_table <- renderTable({all_form_values_rctv()}) observeEvent(input$btn_gen_r_8_form, {
    
    x_id  <- paste( "ns_", str_replace_all(paste(Sys.time()), "-| |:", '') , sep = '')
    gen_forms$all_form_values[[x_id]] <- callModule(module = gen_r_8_form, id = x_id) rctv_uis$all_ui[[x_id]] <- gen_r_8_formUI(id = x_id)

  })
  
  
  all_form_values_rctv <- reactive({
    
    # Question - how to make a tibble with all form values?
    
    # tibble(
    #   forenames = 'all gen_forms$all_form_values forenames', # surnames = 'all gen_forms$all_form_values surnames'
    # )
    
  })
}

shinyApp(ui = ui, server = server)

जवाब

1 starja Aug 18 2020 at 04:37

यहाँ एक समाधान है जो उपयोग करता है insertUI। इसका लाभ यह है कि मौजूदा UI तत्व समान रहते हैं (पिछले मॉड्यूल का कोई रीसेट नहीं) और केवल नए मॉड्यूल जोड़े जाते हैं। यह निर्धारित करने के लिए कि UI कहाँ जोड़ा गया है, फ़ंक्शन tags$div(id = "tag_that_determines_the_position")में परिभाषित करें UI। फिर, insertUIइसे एक तर्क के रूप में लेता है। इसके अतिरिक्त, मैंने कुछ चीजें बदल दी हैं:

  • मॉड्यूल सर्वर फ़ंक्शन के लिए कोड को सरल बनाया, आपको मूल रूप से केवल एक की आवश्यकता है reactive
  • चमकदार 1.5.0 के साथ पेश किए गए नए मॉड्यूल इंटरफ़ेस का उपयोग
  • थोड़ा सरल प्रतिक्रियाशील डेटा संरचना (कम घोंसले के शिकार) का उपयोग करें
library(shiny)
library(stringr)


gen_r_8_formUI <- function(id){
  
  ns <- NS(id)
  
  tagList(fluidRow(column(width = 4, selectInput(ns("slt_forename"), 'forename', choices = unique(c("john", "paul", "george", "ringo")))),
                   column(width = 4, selectInput(ns("slt_surname") , 'surname' , choices = unique(c("lennon", "mccartney", "harrison", "starr"))))))
}

gen_r_8_form <- function(id){
  moduleServer(
    id,
    function(input, output, session) {
      select_values_all <- reactive({tibble(forename  = input$slt_forename,
                                            surname  = input$slt_surname)}) return(list(select_values_all = reactive({select_values_all()}))) } ) } ui <- fluidPage( column(width = 2, actionButton("btn_gen_r_8_form", "GEN R 8 a FORM")), column(width = 6, tags$div(id = "add_UI_here")),
  column(width = 4, tableOutput("all_form_values_table")))

server <- function(input, output) {
  gen_forms                    <- reactiveValues()
  current_id <- 1
  
  observeEvent(input$btn_gen_r_8_form, { x_id <- paste0("module_", current_id) gen_forms[[x_id]] <- gen_r_8_form(id = x_id) insertUI(selector = "#add_UI_here", ui = gen_r_8_formUI(x_id)) current_id <<- current_id + 1 }) all_form_values_rctv <- reactive({ res <- lapply(reactiveValuesToList(gen_forms), function(current_module_output) { current_module_output$select_values_all()
    })
    
    # prevent to show an error message when the first module is added
    if (length(res) != 0 && !is.null(res[[1]]$forename)) { dplyr::bind_rows(res) } else { NULL } }) output$all_form_values_table <- renderTable({
    all_form_values_rctv()
  })
}

shinyApp(ui = ui, server = server)
MrFlick Aug 18 2020 at 03:56

मुझे लगता है कि आप ऐसा कुछ चाहते हैं

  all_form_values_rctv <- reactive({
    dplyr::bind_rows(lapply(gen_forms$all_form_values, function(x) { x$select_values_all()
    }))
  })

आपने सभी मॉडल प्रतिक्रियाशील तत्वों को एकत्र किया है, gen_forms$all_form_valuesताकि आप उन पर पुनरावृति करें और प्रतिक्रियात्मक मूल्य प्राप्त करें और फिर उन सभी तालिकाओं को एक साथ बांधें।