Вот MWE:порядок управления обновлениями в блестящей
library(shiny)
runApp(shinyApp(
ui = pageWithSidebar(
fluidRow(
column(3, wellPanel(
numericInput("numFields", "Select number of fields", 2, min = 1),
br(),
uiOutput("fields"),
br(),
actionButton("goButton", "Go!")
)),
column(3, wellPanel(
uiOutput("morefields")
)),
column(3, wellPanel(
numericInput("numFields2", "Select number of fields 2", 2, min = 1),
br(),
actionButton("goButton2", "Go2!")
))
),
server = function(input, output, session){
output$fields <- renderUI({
numFields <- as.integer(input$numFields)
lapply(1:numFields, function(i) {
textInput(paste0("field", i), paste0("Type in field ", i))
})
})
output$morefields <- renderUI({
if (input$goButton == 0) return(NULL)
isolate({
numFields <- as.integer(input$numFields)
lapply(1:numFields, function(i) {
checkboxInput(paste0("checkbox", i), paste0("Checkbox for field ",
input[[paste0("field", i)]]))
})
})
})
observeEvent(input$goButton2, {
numFields2 <- as.integer(input$numFields2)
last_field <- paste0("field", numFields2)
updateNumericInput(session, "numFields", value = numFields2)
updateTextInput(session, "field1", value = "This is the first field")
updateTextInput(session, last_field, value = "This is the last field")
})
}))
Теперь я выполнить следующий набор действий:
- Запуск приложения
- Установите значение
Select number of fields 2
до, например, 3 - Нажмите кнопку
Go2!
- В левой колонке, количество полей ввода изменяется, но я хотел бы первый и последнее поле для заполнения с текстом, поэтому я нажимаю на кнопку
Go2!
снова - Нажмите на кнопку
Go!
, чтобы создать пользовательский интерфейс в середине.
Моя цель состояла в том, чтобы избежать шагов 4 и 5, но получить тот же результат.
Я попытался решить эту проблему с reactiveValues
-переменными и моделируемой мыши (как это было предложено here):
library(shiny)
library(shinyjs)
jscode <- "shinyjs.click = function(id) { $('#' + id).click(); }"
runApp(shinyApp(
ui = pageWithSidebar(
useShinyjs(),
extendShinyjs(text = jscode),
fluidRow(...)),
server = function(input, output, session){
vals <- reactiveValues(update = 0)
output$fields <- renderUI({...})
output$morefields <- renderUI({...})
observeEvent(input$goButton2, {
numFields2 <- as.integer(input$numFields2)
updateNumericInput(session, "numFields", value = numFields2)
vals$update <- 1
})
observeEvent(vals$update, {
if (vals$update != 1) return(NULL)
numFields2 <- as.integer(input$numFields2)
last_field <- paste0("field", numFields2)
updateTextInput(session, "field1", value = "This is the first field")
updateTextInput(session, last_field, value = "This is the last field")
vals$update <- 2
})
observeEvent(vals$update, {
if (vals$update != 2) return(NULL)
js$click("goButton")
vals$update <- 0
})
}))
Теперь второй пользовательский интерфейс генерируется, но поля остаются пустыми. Я должен нажать на Go2!
три раза, прежде чем все пользовательские интерфейсы полностью обновятся.
Я также попытался сделать следующее в server
-части:
observeEvent(input$goButton2, {
numFields2 <- as.integer(input$numFields2)
updateNumericInput(session, "numFields", value = numFields2)
}, priority = 2)
observeEvent(vals$update, {
numFields2 <- as.integer(input$numFields2)
last_field <- paste0("field", numFields2)
updateTextInput(session, "field1", value = "This is the first field")
updateTextInput(session, last_field, value = "This is the last field")
}, priority = 1)
observeEvent(input$goButton2, {
js$click("goButton")
}, priority = 0)
Опять ход событий выглядит немного по-другому, но все же нажав трижды необходимо, чтобы получить то, что я хочу.
Любые предложения о том, как достичь конечного результата, нажав кнопку Go2!
только один раз?