首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >挂起事件调度

挂起事件调度
EN

Stack Overflow用户
提问于 2022-03-09 08:41:22
回答 2查看 144关注 0票数 2

我有一个带有两个observeEvent()处理程序的应用程序,它们对输入A和输入B作出反应,并做一些事情。事件A的内容之一是更新输入B。

代码语言:javascript
复制
shinyApp(
  ui = fluidPage(
    selectInput("A", "Input A", c(1:5)),
    selectInput("B", "Input B", c(6:10))
  ),
  server = function(input, output, session) {
    observeEvent(input$A, ignoreInit = TRUE, {
      message("Doing A stuff")
      updateSelectInput(session, "B", selected = 10)
    })
    observeEvent(input$B, ignoreInit = TRUE, {
      message("Doing B stuff")
    })
  }
)

因此,改变输入A显然也会触发事件B。我希望事件B只在用户更改输入值时触发,而不是在updateInput完成时触发。是否有一种方法可以在计算表达式时挂起调度事件?我想要这样的:

代码语言:javascript
复制
shinyApp(
  ui = fluidPage(
    selectInput("A", "Input A", c(1:5)),
    selectInput("B", "Input B", c(6:10))
  ),
  server = function(input, output, session) {
    observeEvent(input$A, ignoreInit = TRUE, {
      message("Doing A stuff")
      suspendEventScheduling()
      updateSelectInput(session, "B", selected = 10)
      resumeEventScheduling()
    })
    observeEvent(input$B, ignoreInit = TRUE, {
      message("Doing B stuff")
    })
  }
)

观察员的文档提到了“暂停状态”,但我找不到如何实际使用它的任何例子。

EN

回答 2

Stack Overflow用户

发布于 2022-03-10 13:40:06

在过去,我使用了一个哨兵值模式来处理这些类型的情况(参见下面)。但它总是感觉很脆弱。希望此功能请求能带来更好的选择。

代码语言:javascript
复制
library(shiny)

shinyApp(
  ui = fluidPage(
    selectInput("A", "Input A", c(1:5)),
    selectInput("B", "Input B", c(6:10))
  ),
  server = function(input, output, session) {
    is_server_update <- FALSE
    observeEvent(input$A, {
      message("Doing A stuff")
      updateSelectInput(session, "B", selected = 10)
      # Unchanged value doesn't trigger an invalidation
      if (input$B != 10) {
        is_server_update <<- TRUE
      }
    }, ignoreInit = TRUE)
    observeEvent(input$B, {
      if (is_server_update) {
        is_server_update <<- FALSE
      } else {
        message("Doing B stuff")
      }
    }, ignoreInit = TRUE)
  }
)
票数 0
EN

Stack Overflow用户

发布于 2022-03-11 12:43:27

在玩了几次之后,我收集了一些JavaScript来完成这个任务。

这样做的目的是跟踪其值不应改变的暂停输入。使用事件钩子,我们可以检查一个输入事件是否针对一个挂起的输入。如果是这样的话,就阻止它进行更改。但关键的是,UI仍然会得到更新--只是不会更新闪亮的输入值。

然后,我们还需要一些帮助函数来管理挂起的输入列表。这是JavaScript和R助手:

代码语言:javascript
复制
js <-
  "
  // Don't actually modify the Shiny object in 'real' code!
  Shiny.suspendedInputs = new Set();
  
  $(document).on('shiny:inputchanged', function(event) {
    Shiny.suspendedInputs.has(event.target.id) && event.preventDefault();
  })
  
  Shiny.addCustomMessageHandler('suspendinput', function(message) {
    Shiny.suspendedInputs.add(message.id);
  });
  
  Shiny.addCustomMessageHandler('resumeinput', function(message) {
    Shiny.suspendedInputs.delete(message.id);
    
    // Last value that Shiny got is probably out of sync with the UI
    Shiny.forgetLastInputValue(message.id);
  })
  "

suspendInput <- function(inputId, session = getDefaultReactiveDomain()) {
  session$sendCustomMessage("suspendinput", list(id = inputId))
}

resumeInput <- function(inputId, session = getDefaultReactiveDomain()) {
  session$sendCustomMessage("resumeinput", list(id = inputId))
}

几乎所有的挂起和恢复消息都应该在不同的刷新周期中发送。否则,将在任何更新的输入事件触发之前执行简历,从而不会发生任何事情。另一个确保“正确”使用的助手应该是:

代码语言:javascript
复制
suspendForNextFlush <- function(inputId, session = getDefaultReactiveDomain()) {
  session$onFlush(function() suspendInput(inputId, session = session))
  session$onFlushed(function() resumeInput(inputId, session = session))
}

现在,我们已经准备好将所有的东西整合到一个工作的应用程序中:

代码语言:javascript
复制
library(shiny)

shinyApp(
  ui = fluidPage(
    tags$script(HTML(js)),
    selectInput("A", "Input A", c(1:5)),
    selectInput("B", "Input B", c(6:10))
  ),
  server = function(input, output, session) {
    observeEvent(input$A, {
      message("Doing A stuff")
      suspendForNextFlush("B")
      updateSelectInput(session, "B", selected = 10)
    }, ignoreInit = TRUE)
    observeEvent(input$B, {
      message("Doing B stuff")
    }, ignoreInit = TRUE)
  }
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71406486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档