блестящий динамически добавлять поля ввода и данные без повторного рендеринга - PullRequest
2 голосов
/ 23 марта 2020

Я пытаюсь динамически добавлять новые переменные в мое блестящее приложение, которое работает, но если я начинаю редактировать одну, значения (текст и цифры c) сбрасываются каждый раз, когда я добавляю дополнительную переменную. Этот пример работает без необходимости для l oop, используя reactiveValuesToList(), но когда я применяю его к своему коду, он не работает. Вот мой рабочий пример:

library(shiny)
dist <- c("Normal", "Gamma")
ui <- shinyUI(fluidPage(

  sidebarPanel(

    actionButton("add_btn", "Add Textbox"),
    actionButton("rm_btn", "Remove Textbox"),
    textOutput("counter")

  ),

  mainPanel(uiOutput("textbox_ui"))

))

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

  # Track the number of input boxes to render
  counter <- reactiveValues(n = 0)

  # Track all user inputs
  AllInputs <- reactive({
    x <- reactiveValuesToList(input)
  })

  observeEvent(input$add_btn, {counter$n <- counter$n + 1})
  observeEvent(input$rm_btn, {
    if (counter$n > 0) counter$n <- counter$n - 1
  })

  output$counter <- renderPrint(print(counter$n))

  textboxes <- reactive({

    n <- counter$n

    if (n > 0) {
      isolate({
        lapply(seq_len(n), function(i) {
        fluidRow(
          selectInput(inputId = paste0("news", i),
                      label = paste0("Variable ", i),
                      choices = dist),

          conditionalPanel(
            condition = sprintf("input.%s=='Normal'", paste0("news", i)),
            textInput("txt", "Text input:", paste0("var", i)),  
            column(width = 3, numericInput('normal_mean', 'Mean', value = '0')), column(width = 3, numericInput('normal_sd', 'Standard deviation', value = '1'))),

          conditionalPanel(
            condition =  sprintf("input.%s=='Gamma'", paste0("news", i)),
            textInput("txt", "Text input:", paste0("var", i)),
            column(width = 3, numericInput('gamma_shape', 'Shape', value = '0')), column(width = 3, numericInput('gamma_scale', 'Scale', value = '1')))
        )
        })
      })
    }

  })

  output$textbox_ui <- renderUI({ textboxes() })

})

shinyApp(ui, server)

Теперь, если я попытаюсь добавить AllInputs()[[]] к textInput, он не сохранит текст в вызове conditionalPanel:

conditionalPanel(
            condition = sprintf("input.%s=='Normal'", paste0("news", i)),
            textInput("txt", "Text input:", AllInputs()[[paste0("var", i)]]),  
            column(width = 3, numericInput('normal_mean', 'Mean', value = '0')), column(width = 3, numericInput('normal_sd', 'Standard deviation', value = '1')))

Я также не уверен, как включить AllInputs()[[]] в числовые значения c, чтобы они не менялись.

Я думаю, что проблема в том, что моя строка condition внутри conditionalPanel, но может не понял, какие-либо предложения? спасибо

1 Ответ

4 голосов
/ 24 марта 2020

Вам следует рассмотреть возможность использования модулей и insertUI / removeUI. Нажатие на кнопки не сбрасывает ваши изменения на входах, которые вы уже вызывали. Здесь у вас есть только входы, поэтому вам нужно только вызвать функцию add_box, которую я создал, но если вы хотите добавить выходы в модуль, вам нужно будет использовать функцию callModule в observeEvent. Это объясняется в статье, на которую я ссылаюсь.

Это не тот метод, который вы предложили, но он работает.

library(shiny)

dist <- c("Normal", "Gamma")

add_box <- function(id){
  ns <- NS(id)
  tags$div(id = paste0("new_box", id),
           selectInput(inputId = ns("news"),
                       label = paste0("Variable ", id),
                       choices = dist),

           conditionalPanel(
             condition = "input.news=='Normal'",
             ns = ns,
             textInput(ns("txt"), "Text input:", paste0("var", id)),  
             column(width = 3, numericInput(ns('normal_mean'), 'Mean', value = '0')), 
             column(width = 3, numericInput(ns('normal_sd'), 'Standard deviation', value = '1'))),

           conditionalPanel(
             condition =  "input.news=='Gamma'",
             ns = ns,
             textInput(ns("txt"), "Text input:", paste0("var", id)),
             column(width = 3, numericInput(ns('gamma_shape'), 'Shape', value = '0')), 
             column(width = 3, numericInput(ns('gamma_scale'), 'Scale', value = '1')))
  )
}


ui <- shinyUI(fluidPage(

  sidebarPanel(

    actionButton("add_btn", "Add Textbox"),
    actionButton("rm_btn", "Remove Textbox"),
    textOutput("counter")

  ),

  mainPanel(column(width = 12, id = "column"))

))

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

  # Track the number of input boxes to render
  counter <- reactiveValues(n = 0)

  # Track all user inputs
  AllInputs <- reactive({
    x <- reactiveValuesToList(input)
  })

  observeEvent(input$add_btn, {
    counter$n <- counter$n + 1
    insertUI(selector = "#column",
             where = "beforeEnd",
             ui = add_box(counter$n)
    )
  })

  observeEvent(input$rm_btn, {
    if (counter$n > 0) {
      removeUI(selector = paste0("#new_box", counter$n))
      counter$n <- counter$n - 1
    }
  })

  output$counter <- renderPrint(print(counter$n))


})

shinyApp(ui, server)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...