选择不同的过滤器时,将 input$mytime_selected 值重置为 NULL

Reset input$mytime_selected value back to NULL in timevis when a different filter is chosen

我有一个闪亮的应用程序,其中有 2 个过滤器选项("an option" 和 "another option")。时间轴以 "an option" 选中开始。如果用户在时间轴中选择了一个项目,则会出现一些文本。我想做的是,如果用户在时间轴中选择了某些内容,则将 input$timeline_selected 值设置回 NULL,然后在清除选择之前选择不同的过滤器选项。例如,在这个简单的应用程序中,如果用户将过滤器设置为 "an option",然后在时间轴上选择 "item one",然后在清除选择之前将过滤器更改为 "another option","selection id" 仍然是 1,即使在更改过滤器时该项目未显示在时间线上。

我希望发生的情况如下:用户将过滤器设置为 "an option",然后在时间轴上选择 "item one",然后将过滤器更改为 "another option"(之前清除选择),然后输入 $timeline_selected 值重置为 NULL。

library(shiny)
library(dplyr)

dataBasic <- data.frame(
  id = 1:4,
  content = c("Item one", "Item two" ,"Ranged item", "Item four"),
  start   = c("2016-01-10", "2016-01-11", "2016-01-20", "2016-02-14"),
  end    = c(NA, NA, "2016-02-04", NA), 
  selection = c("an option", "an option", "another option", "another option")
)


ui <- fluidPage(
  sidebarPanel(radioButtons(inputId = "filter",
               label = "Select filter:",
               choices = unique(dataBasic$selection),
               selected = "an option")
  ),
  mainPanel(wellPanel(timevisOutput("timeline")
                      ), 
            wellPanel(htmlOutput(outputId = "text"),
                      textOutput("selected", inline = TRUE)
                      )
            )
)

server <- function(input, output){
  # Create timeline
  output$timeline <- renderTimevis({
    req(input$filter)
    dataBasic %>% 
      filter(selection == input$filter) %>% 
      timevis()
  })


  output$text <- renderText({

    if (!is.null(input$timeline_selected)) {
      input$timeline_data %>% 
        filter(id == input$timeline_selected) %>% 
        pull(content)
    }
  })

  output$selected <- renderText(
    paste("selection id: ", input$timeline_selected)
  )

  # clear selection if different filter is chosen
  # observeEvent(input$filter, {
  #    input$timeline_selected <- NULL
  #  })

}
shinyApp(ui = ui, server = server)

我尝试使用

observeEvent(input$filter, {
      input$timeline_selected <- NULL
    })

但随后我收到一条错误消息 "Attempted to assign value to a read-only reactivevalues object"

我考虑过使用 setSelection,但在输入 $mytime_selected 下的 timevis 帮助中它指出 "Note that this will not get updated if an item is selected programmatically using setSelection."

我的应用程序比这个例子更复杂,我根据 id 过滤数据,当我将过滤器从一个选项更改为另一个选项时它显示错误,因此能够重置输入 $timeline_selected 值返回 NULL 将解决我的问题。

在此先感谢您的帮助!

您可以简单地引入一个 reactiveValue 作为中间变量:

  1. 每次更改时都采用 input$timeline_selected 的值
  2. input$filter 的值改变时设置为 NULL

将以下代码添加到您的 server 函数中:

# Define reactiveValue
rv <- reactiveValues(selected = NULL)

# 1. Pass value of input$timeline_selected to Reactive Value
observe( {
  rv$selected <- input$timeline_selected
})

# 2. clear selection if different filter is chosen
observeEvent(input$filter, {
  rv$selected <- NULL
})

然后把代码中的input$timeline_selected改成反应值:

output$text <- renderText({
  if (!is.null(rv$selected)) {
    input$timeline_data %>% 
      filter(id == rv$selected) %>% 
      pull(content)
  }
})

output$selected <- renderText(
  paste("selection id: ", rv$selected)
)

请注意,包中可能有我不熟悉的更琐碎的解决方案。