R闪亮:如何触发onRestored或观察者

问题描述 投票:0回答:1

以下应用程序具有两个输入,而第二个输入依赖于第一个输入并在服务器站点上更新。如何实现书签,使第二个变量(Input2)在使用链接恢复站点时仅更新一次?

df <- structure(list(Input1 = c("A", "A", "A", "A", "A", "B", "B", 
                          "B", "B", "B", "C", "C", "C", "C", "C"), Input2 = c(1L, 2L, 3L, 
                          5L, 7L, 2L, 4L, 6L, 7L, 8L, 1L, 4L, 5L, 6L, 7L)), class = c("grouped_df", 
                          "tbl_df", "tbl", "data.frame"), row.names = c(NA, -15L), groups = structure(list(
                           Input1 = c("A", "B", "C"), .rows = structure(list(1:5, 6:10,  11:15), ptype = integer(0), class = c("vctrs_list_of", 
                           "vctrs_vctr", "list"))), row.names = c(NA, -3L), .drop = TRUE, class = c("tbl_df", "tbl", "data.frame")))

shinyApp(
  ui = function(request) {fluidPage(
    selectInput("input1", "input1", choices = unique(df$Input1)),
    selectInput("input2", "input2", choices = NA)
  )},
  server = function(input, output, session){
    observe({
      req(input$input1)
      
      tmp_input2 <- df %>% 
        filter(Input1 == input$input1) %>% 
        pull(Input2)
      updateSelectInput(session, "input2", choices = tmp_input2)
    })
    
    
    observe({
     session$doBookmark()
    })
    onBookmarked(function(url) {
      updateQueryString(url)
    })
    
    onRestored(function(state) {
      updateSelectInput(session, "input2", selected = state$input$input2)
      })
    
    
    observe({
      print(input$input2)
    })
    
  },enableBookmarking = "url")

使用例如恢复网站时此链接http://127.0.0.1:6279/?_inputs_&input1=%22A%22&input2=%225%22

然后你可以在控制台中观察到首先是观察者被触发,而不是onRestore。这在这个应用程序中没有问题,但是我的在这里触发了一个需要一些时间的事件,并且由于它被触发两次(观察者,而不是 onRestored),因此用户体验减少了两倍。

我尝试使用逻辑向量(

restored
),该向量在 onRestored 函数中设置为 TRUE,但没有成功。

在恢复时在观察者内部设置 req(restored) 是有效的,但当网站空白启动时当然会失败。

onRestore
,因为它是在所有观察者之前触发的,所以是完美的,但由于需要
Input1
来“计算”
Input2
,这是不可能的。

r shiny
1个回答
0
投票

onRestore
就是要走的路。问题是,您无法定义
selected
值,该值不存在于选项中:

library(shiny)
library(dplyr)

DF <- structure(list(Input1 = c("A", "A", "A", "A", "A", "B", "B", 
                          "B", "B", "B", "C", "C", "C", "C", "C"), Input2 = c(1L, 2L, 3L, 
                          5L, 7L, 2L, 4L, 6L, 7L, 8L, 1L, 4L, 5L, 6L, 7L)), class = c("grouped_DF", 
                          "tbl_DF", "tbl", "data.frame"), row.names = c(NA, -15L), groups = structure(list(
                           Input1 = c("A", "B", "C"), .rows = structure(list(1:5, 6:10,  11:15), ptype = integer(0), class = c("vctrs_list_of", 
                           "vctrs_vctr", "list"))), row.names = c(NA, -3L), .drop = TRUE, class = c("tbl_DF", "tbl", "data.frame")))

shinyApp(
  ui = function(request) {
    fluidPage(
      selectInput("input1", "input1", choices = unique(DF$Input1)),
      selectInput("input2", "input2", choices = NA)
    )
  },
  server = function(input, output, session) {
    restored_session <- reactiveVal(FALSE)
    observe({
      if(!restored_session()){
        req(input$input1)
        tmp_input2 <- DF %>%
          filter(Input1 == input$input1) %>%
          pull(Input2)
        updateSelectInput(session, "input2", choices = tmp_input2) 
      }
    })
    # observe({
    #   session$doBookmark()
    # })
    onBookmarked(function(url) {
      updateQueryString(url)
    })
    onRestore(function(state) {
      restored_session(TRUE)
    })
    onRestored(function(state) {
      updateSelectInput(session, "input2", choices = state$input$input2, selected = state$input$input2)
    })
    observe({
      print(input$input2)
    })
  },
  enableBookmarking = "url"
)
© www.soinside.com 2019 - 2024. All rights reserved.