Работая над приложением, я пришел к одной (из многих) мелочей, с которыми у меня возникли проблемы.
У меня есть пользователь, заполняющий textInputs
в conditionalPanel
, и после нажатия actionButton
появляется другая условная панель, которая включает ту же информацию в форме data.table
.
Моя проблема, похоже, заключается в функции rbind
в сочетании с функцией assignment operator
. Я не использую его, таблица (Panel2) будет включать только первую строку пользовательского ввода из Panel1. Если я использую rbind, он возвращает таблицу, которую я ожидаю (несколько входных строк приводят к нескольким строкам в таблице данных).
Но после закрытия и перезапуска моего приложения rbind добавляет новый ввод к старому.
Скажем, мой первый ввод будет:
A B C
после закрытия и перезапуска я набираю:
D E F
и результат был бы
A B C
D E F
но я хочу только: D E F
быть в моей таблице.
Пожалуйста, взгляните на мой код:
library(shiny)
library(DT)
library(data.table)
ui = fluidPage(
conditionalPanel(
condition = "input.createTemplTable%2 == 0",
actionButton("add", "Add new Row", icon=icon("plus", class=NULL, lib="font-awesome")),
actionButton("remove", "Remove last Row", icon=icon("times", class = NULL, lib = "font-awesome")),
fluidRow(
column(2,
textInput("first", label = h5("first"))
),
column(2,
textInput("second", label = h5("second"))
),
column(2,
textInput("third", label = h5("third"))
)
),
tags$div(id = 'placeholder'),
actionButton("createTemplTable", "Create Template")
),
conditionalPanel(
condition = "input.createTemplTable%2 == 1",
#actionButton("return", "Return to Template Generator"),
dataTableOutput("createdTempl")
)
)
server = function(input, output) {
## keep track of elements inserted and not yet removed
inserted <- reactiveValues(val = 0)
tableColumns <- c("first", "second", "third")
observeEvent(input$add, {
id <- length(inserted$val) + 1
insertUI(
selector = "#placeholder",
where = "beforeBegin",
ui =tags$div(
id = id,
fluidRow(
column(2,
textInput("first", label = (""))
),
column(2,
textInput("second", label = (""))
),
column(2,
textInput("third", label = (""))
)
)
)
)
inserted$val <- c(inserted$val, id)
})
observeEvent(input$remove,{
print(inserted$val)
removeUI(
selector = paste0('#', inserted$val[length(inserted$val)])
)
inserted$val <- inserted$val[-length(inserted$val)]
})
saveData <- function(data) {
data <- as.data.table(t(data))
if (exists("createdTempl")) {
createdTempl <<- rbind(createdTempl, data)
} else {
createdTempl <<- data
}
}
loadData <- function() {
if (exists("createdTempl")) {
createdTempl
}
}
formData <- reactive({
data <- sapply(tableColumns, function(x) input[[x]])
data
})
observeEvent(input$createTemplTable, {
saveData(formData())
})
output$createdTempl <- renderDataTable({
input$createTemplTable
loadData()
})
}
shinyApp(ui = ui, server = server)
Нужно ли использовать сеанс? Если да, то как бы я это сделал? Спасибо!
createdTempl
является глобальной переменной, которая является общей для всех сеансов. Вместо этого вы должны использовать реактивные значения. - person SBista   schedule 31.05.2017