R Shinny-updateSelectizeInput在observeEvent与actionButton结合时不更新输入

R Shinny-updateSelectizeInput在observeEvent与actionButton结合时不更新输入,r,shiny,R,Shiny,问题:在observeEvent中调用updateSelectizeInput会更改浏览器中显示的值,但不会更改我可以使用input$从代码访问的值 背景:在我的闪亮应用程序中,我希望输入具有以下属性的内容: 用户可以输入并从服务器端选项列表中选择 URL查询字符串也可以控制它 空白表示所有选项 actionButton允许用户延迟昂贵的计算,直到做出所有想要的选择 我当前有一个observeEvent监视查询字符串,当它看到一个字符串时,它调用updateSelectizeInput,但是,在

问题:在
observeEvent
中调用
updateSelectizeInput
会更改浏览器中显示的值,但不会更改我可以使用
input$从代码访问的值

背景:在我的闪亮应用程序中,我希望输入具有以下属性的内容:

  • 用户可以输入并从服务器端选项列表中选择
  • URL查询字符串也可以控制它
  • 空白表示所有选项
  • actionButton允许用户延迟昂贵的计算,直到做出所有想要的选择
  • 我当前有一个
    observeEvent
    监视查询字符串,当它看到一个字符串时,它调用
    updateSelectizeInput
    ,但是,在它这样做之后,输入保持不变

    示例

    library(shiny)
    
    possibleLetters = LETTERS[1:10]
    
    ui <- fluidPage(
       
       sidebarLayout(
          sidebarPanel(
            selectizeInput(inputId='letters', 
                           label='Your letters:', 
                           choices=NULL,
                           selected=NULL, 
                           multiple=T, 
                           width='100%'),
            actionButton("recompute",
                         "Recompute now")
          ),
          
          mainPanel(
            h3("Letters: "),
            textOutput('lettersDisplay'),
            h3("Indices of letters: "),
            textOutput('lettersIndicesDisplay')
          )
       )
    )
    
    server <- function(input, output, session) {
       
      updateSelectizeInput(inputId='letters',
                           choices=c('',possibleLetters),
                           server=T)
    
      userLetters = eventReactive(input$recompute, ignoreNULL=FALSE, {
        if (length(input$letters) == 0) {
          return (possibleLetters)
        } else (
          return (input$letters)
        )
      })
      
      userLetterIndices = reactive({
        return(match(userLetters(),LETTERS))
      })
      
      queryStringObserver = observeEvent(session$clientData$url_search, {
        query <- parseQueryString(session$clientData$url_search)
        if (!is.null(query$letters)) {
          cat(file=stderr(), paste0('observeEvent running - user specified param is: ',query$letters,'\n'))
          updateSelectizeInput(session, 
                               inputId="letters",
                               choices = possibleLetters,
                               selected = query$letters,
                               server=T)
          cat(file=stderr(), paste0('observeEvent running - ran updateSelectizeInput, input$letters is now: ',input$letters,'\n'))
        }
      })
      
      
      output$lettersDisplay = renderText({
        return(paste(userLetters(),collapse=' '))
      })
      
      output$lettersIndicesDisplay = renderText({
        return(paste(userLetterIndices(), collapse=' '))
      })
    
    }
    
    shinyApp(ui = ui, server = server, options = list(port=1111))
    
    
    因此,查询字符串已被正确解析,调用了
    updateSelectizeInput
    ,但当随后访问
    input$letters
    时,其值没有改变


    我怀疑这与我在理解反应图或其他方面的一些基本缺陷有关,但是在仔细研究了如何使用Shiny之后,我仍然不明白为什么这个调用什么都不起作用。

    input$letters的值更新了,在您尝试打印它时它还没有更新。我不确定这些消息是如何批处理的或是否批处理的,但您的
    observeEvent
    最终会触发一条消息,发送给客户端以更新输入,然后必须通知服务器已更新。至少,我假设它将完成当前观察者代码的执行,但通过一些修补,它可能会在向客户端发送消息之前执行所有必要的反应式代码

    虽然
    input$letters
    的值不打印给定代码,但如果单击“重新计算”,它会按预期更新文本。基本上,以下是我认为与您的代码按原样进行的或多或少的对话:

    Client: Yo, server. The user added a query parameter: letters=A.
    
    Server: Hmmm, ok I will just run this observeEvent code. Oh, the developer wants to know the current value of `input$letters`. Client, can you help a server out with that input value.
    
    Client: No problem, friend-o. The current selected value is NULL.
    
    Server: Well, let me just cat this NULL to the stderr. 
    
    Server (~1 ms later): Yo, client. I finished running the observeEvent code and you should really update that selectize input. It would make everyone happy.
    
    Client: Can do.
    
    Client (~2 ms later): Whoa, the select input updated. I gots to tell server about this jawn. Hey server, input$letters just changed to `A`. Just FYI.
    
    Server: Hmm, good to know. Nothing for me to do about that.
    
    当服务器打印
    inputletters
    时,该值仍然为空,因为它尚未通知客户端更新它。实际上,我不确定服务器是否轮询客户机以获取该值,或者是否从它自己的当前值列表中查找该值,但无论哪种方式,当它转到cat值时,它仍然没有被更新

    将您的
    cat
    语句移动到一个单独的
    observe
    语句,上面的对话将更改为

    Client (~2 ms later): Whoa, the select input updated. I gots to tell server about this jawn. Hey server, input$letters just changed to `A`. Just FYI.
    
    Server: WHAT?!!! OMG! I MUST TELL STDERR ABOUT THIS!!
    

    这是一个漫长的过程,我不认为你的代码本身有任何问题。抱歉,对于服务器和客户端的所有个性变化,希望这能有所帮助。

    Ha,谢谢,这非常有帮助,我喜欢这段对话!这就给我留下了一个遗留问题,那就是如何在对
    input$letters
    的更改最终完成后,运行名为
    userlets
    eventReactive
    。现在,它没有,将
    queryStringObserver
    session$clientData$url\u search
    添加到它的
    eventExpr
    不会改变这一点。有什么想法吗?为了确保我了解所需的状态:当用户更改selectize输入(
    字母
    )时,文本显示在单击“立即重新计算”之前不会更新。包含/更改查询字符串时,文本显示应自动更新?是的,完全正确!那是我的愿望。
    Client (~2 ms later): Whoa, the select input updated. I gots to tell server about this jawn. Hey server, input$letters just changed to `A`. Just FYI.
    
    Server: WHAT?!!! OMG! I MUST TELL STDERR ABOUT THIS!!