Получение входных данных от модулей, созданных с помощью insertUI - PullRequest
0 голосов
/ 18 марта 2019

В моем приложении есть модуль, который я буду создавать динамически, используя insertUI.Я пытаюсь найти способ запечатлеть выходные данные этого модуля.В приложении ниже есть простой модуль, который состоит из элемента textInput.Серверная часть возвращает значение этого элемента textInput и сообщает, что он активен.Я пытаюсь захватить это возвращаемое значение.

Я пытался создать объект reactiveValues, чтобы получить выходные данные модулей, но этот объект не обновляется при изменении ввода.Сам код модуля работает, так как я получаю сообщение, которое приходит из модуля, но внешние команды наблюдения, которые проверяют reactiveValues, выполняются только после их повторного создания.Как я могу получить эти значения извне модуля

library(shiny)

# a module that only has a text input
moduleUI = function(id){
    ns = NS(id)
    tagList(
        # the module is enclosed within a div with it's own id to allow it's removal
        div(id = id,
            textInput(ns('text'),label = 'text'))
    )
}

# the module simply returns it's input and reports when there is a change
module = function(input,output,session){
    observeEvent(input$text,{
        print('module working')
    })
    return(input$text)
}


# ui is iniated with add/remove buttons
ui = fluidPage(
    actionButton('add','+'),
    actionButton('remove','-')
)

server = function(input, output,session) {
    # number of ui elements already created
    uiCount = reactiveVal(0)

    moduleOuts = reactiveValues()

    observeEvent(input$add,{
        # count the UI elements created to assign new IDs
        uiCount(uiCount()+1)
        # insert module UI before the add/remove buttons
        insertUI('#add',
                 'beforeBegin',
                 moduleUI(paste0("module",uiCount())))

        # failed attempt to get the output
        moduleOuts[[as.character(uiCount())]] = callModule(module,id = paste0("module",uiCount()))
    })

    observeEvent(input$remove,{
        # if remove button is pressed, remove the UI and reduce the UI count
        removeUI(
            selector = paste0("#module",uiCount())
        )
        uiCount(uiCount()-1)
    })

    # simple test
    observe({
        print(moduleOuts[['1']])
    })

    # test to get all values
    observe({
        seq_len(uiCount()) %>% sapply(function(i){
            print(moduleOuts[[as.character(i)]])
        })
    })

}


shinyApp(ui = ui, server = server)

1 Ответ

2 голосов
/ 19 марта 2019

Проблема здесь проста: вам нужно явно возвращать значение как реактивное.return(reactive(input$text))

Возвращая просто input$text, вы, по сути, просто возвращаете его в определенный момент времени, поскольку input$text - это просто значение.Обернув его в reactive(), вы теперь возвращаете реактивное выражение.Код сервера должен соответствовать этому, поэтому я добавил () к коду, который обращается к этому значению.

Я удалил «простой тест», потому что он вызывал ошибку, так как этот модуль изначально не существует.

library(shiny)

# a module that only has a text input
moduleUI = function(id){
  ns = NS(id)
  tagList(
    # the module is enclosed within a div with it's own id to allow it's removal
    div(id = id,
        textInput(ns('text'),label = 'text'))
  )
}

# the module simply returns it's input and reports when there is a change
module = function(input,output,session){
  observeEvent(input$text,{
    print('module working')
  })
  return(reactive(input$text))
}


# ui is iniated with add/remove buttons
ui = fluidPage(
  actionButton('add','+'),
  actionButton('remove','-')
)

server = function(input, output,session) {
  # number of ui elements already created
  uiCount = reactiveVal(0)

  moduleOuts = reactiveValues()

  observeEvent(input$add,{
    # count the UI elements created to assign new IDs
    uiCount(uiCount()+1)
    # insert module UI before the add/remove buttons
    insertUI('#add',
             'beforeBegin',
             moduleUI(paste0("module",uiCount())))

    # failed attempt to get the output
    moduleOuts[[as.character(uiCount())]] = callModule(module,id = paste0("module",uiCount()))
  })

  observeEvent(input$remove,{
    # if remove button is pressed, remove the UI and reduce the UI count
    removeUI(
      selector = paste0("#module",uiCount())
    )
    uiCount(uiCount()-1)
  })

  # test to get all values
  observe({
    seq_len(uiCount()) %>% sapply(function(i){
      print(moduleOuts[[as.character(i)]]())
    })
  })

}


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