Как скрыть/показать сразу несколько элементов с помощьюshiningjs?

Как hide/show сразу несколько элементов с помощьюshiningjs? В следующем примере моя цель — скрыть/показать обе таблицы всего двумя строками кода вместо четырех. Почему я хочу это сделать? На самом деле я имею дело с несколькими таблицами и несколькими событиями, так что показ/скрытие их всех сразу сделает код намного чище.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  actionButton("hide","Hide!"),
  actionButton("show","Show!"),
  tableOutput("table1"),
  tableOutput("table2"))

server <- function(input, output, session) {
  output$table1 <- renderTable({head(iris)})
  output$table2 <- renderTable({head(iris)})
  observeEvent(input$hide, {hide("table1")})
  observeEvent(input$show, {show("table1")})
  observeEvent(input$hide, {hide("table2")})
  observeEvent(input$show, {show("table2")})}

shinyApp(ui, server)

person Joe    schedule 13.10.2017    source источник


Ответы (1)


Вы можете написать функцию, которая выполняет обе операции и вызывает их один раз для каждого элемента пользовательского интерфейса, который вы хотите скрыть/показать.

library(shiny)
library(shinyjs)

toggleView <- function(input, output_name){
  observeEvent(input$show, {show(output_name)})
  observeEvent(input$hide, {hide(output_name)})
}

ui <- fluidPage(
  useShinyjs(),
  actionButton("hide","Hide!"),
  actionButton("show","Show!"),
  tableOutput("table1"),
  tableOutput("table2"))

server <- function(input, output, session) {
  output$table1 <- renderTable({head(iris)})
  output$table2 <- renderTable({head(iris)})
  toggleView(input, "table1")
  toggleView(input, "table2")
}

shinyApp(ui, server)

Вы также можете сделать еще один шаг и веркоризировать эту функцию по отношению к output_name. Однако обязательно используйте lapply, а не for, так как последний может столкнуться с проблемами ленивых вычислений.

toggleViews <- function(input, output_names){
  lapply(output_names, function(output_name){
    toggleView(input, output_name)
  })
}

...

toggleViews(input, c("table1", "table2"))
person Gregor de Cillia    schedule 13.10.2017
comment
Большой! Зачем нам input в качестве аргумента для toggleView? Пробовал без, не получилось. - person Joe; 13.10.2017
comment
Если вы определяете функцию toggleView внутри сервера, аргумент input не нужен. Кроме того, вы также можете взломать среду с помощью input = getDefaultReactiveDomain()$input - person Gregor de Cillia; 13.10.2017
comment
Что-то не так с определением toggleView внутри server? - person Joe; 13.10.2017
comment
Размещение определений функций/объектов вне сервера (в global.R) имеет смысл, если они (1) требуют много времени для запуска или (2) используются в ui.R и server.R. В данном случае ни один из этих двух критериев не соблюдается. - person Gregor de Cillia; 13.10.2017
comment
Я только что отредактировал ответ, чтобы разрешить ввод векторов в output_name. Возможно, таким образом вы сможете сохранить несколько дополнительных строк кода. - person Gregor de Cillia; 13.10.2017