Это мой первый вопрос к SO, и я постараюсь быть максимально кратким и ясным.
Я модифицирую одну версию базового c Shiny CRUD, предоставленного Дином Аттали (которому: спасибо) для исследовательских целей. Для этого я создал игрушку MRE (см. Ниже), которая демонстрирует основные модели поведения, которых я пытаюсь достичь.
- Пользовательские фильтры отображают данные, основанные на реактивном (refreshData () input $ item_used)
- Пользователь может добавлять или удалять новые записи (saveData (), deleteData ())
- Пользователь может щелкать строки и динамически просматривать реактивные изменения через DT :: dataTableOutput.
Моя проблема заключается в следующем: если пользователь добавляет новую запись, и видимые данные DT фильтруются по одному из двух вариантов в раскрывающемся списке, тогда активное представление DT не обновляет . Предположим, пользователь добавляет новую запись к элементам «B», при этом все элементы и только элементы «B» отображаются в таблице (фильтруются через раскрывающийся список) - чтобы увидеть новую запись, ей необходимо выберите элементы «A», а затем снова выберите элементы «B», чтобы «обновить sh» таблицу, чтобы увидеть новую запись.
Я знаю, что здесь есть простое решение, основанное на реактивности, но я не могу его идентифицировать. Будем признательны за вашу коллективную помощь!
library(shiny)
library(shinyjs)
# Define the fields we want to save from the form
fields <- c("name", "item_used", "notes")
data <- data.frame(name = c("Luthien","Aredhel","Beren","Turin"),
item_used = c("A","B","A","B"),
notes = c("fixed","not broken","almost fixed", "beyond repair"),
stringsAsFactors = FALSE)
# Shiny app with 3 fields that the user can submit data for
shinyApp(
ui = fluidPage(sidebarLayout(
sidebarPanel(width = 3,
selectInput("select_used", "Item Used?", choices = c("", "A","B")),
tags$hr(),
lapply(1:length(fields), function(x) textInput(fields[x], fields[x])),
actionButton("submit", "Submit"),
actionButton("delete", "Delete")
),
mainPanel(DT::dataTableOutput("maindata", width = 300),
tags$hr()
))),
server = function(input, output, session) {
# Whenever a field is filled, aggregate all form data
formData <- reactive({
data <- sapply(fields, function(x) input[[x]])
data
})
# When the Submit button is clicked, save the form data
observeEvent(input$submit, {
saveData(formData())
})
# Show the previous responses
# (update with current response when Submit is clicked)
output$maindata <- DT::renderDataTable({
input$delete
input$submit
refreshData()
})
observeEvent(input$maindata_rows_selected, {
dat <- refreshData()[input$maindata_rows_selected,]
for(i in 1:length(dat)){
updateTextInput(session, fields[i], value = unname(dat[i]))
}
})
observeEvent(input$delete,{
deleteData()
})
deleteData <- function(){
delrow <- row.names(refreshData()[input$maindata_rows_selected,])
data <- loadData()[-c(as.numeric(delrow)),]
data <<- data
}
loadData <- function(){
data <- data
return(data)
}
saveData <- function(data) {
data <- rbind(loadData(), formData())
data <<- data
}
refreshData <- reactive({
data <- loadData()
if(input$select_used == ""){
data
} else {
data[data$item_used == input$select_used, ]
}
})
}
)