代码之家  ›  专栏  ›  技术社区  ›  thothal

在闪光中执行观察员的命令

  •  0
  • thothal  · 技术社区  · 6 年前

    目标和当前方法

    我有一个模块,它可以删除自己的用户界面。我还希望能够从模块外部调用这个杀戮功能,因此我向模块的服务器逻辑传递了一个额外的反应,并在这个反应性触发时调用杀戮例程。

    到现在为止,一直都还不错。现在,我想实现一个函数,它首先杀死我模块的所有实例,然后添加这个模块的新实例,这就是我所选择的设计的难点所在。

    问题

    我需要的是在我 input$add5 观察者添加任何新的实例,所有旧的实例都会被杀死。这可以通过设置 kill_switch(TRUE) 但问题是在 observer 在我的模块中可以对此作出反应, 输入$ADD5 观察者继续添加新的模块,这些模块将重置 kill_switch FALSE 基本上,旧的例子永远不会被杀死。

    基本上,在当前的设计中,我希望 观察者 基尔开关 在我更改标志后立即做出反应,只有在完成此操作后,我的 add5 观察者继续。

    我需要什么

    我认为我的设计不是最优的,因此任何关于如何在主应用程序和模块之间建立接口的建议都会受到高度赞赏。


    代码

    library(shiny)
    
    boxer_ui <- function(id) {
      ns <- NS(id)
      div(
        id,
        id = ns("killme"), 
        style = "background-color:steelblue; font-size: xx-large; color: white")
    }
    
    boxer <- function(input, output, session, kill_switch) {
      ns <- session$ns
      observe({
        req(kill_switch())
        removeUI(paste0("#", ns("killme")))
      })
    }
    
    ui <- fluidPage(actionButton("new", "new"), 
                    actionButton("killall", "Kill All"), 
                    actionButton("add5", "Kill All & Add 5"),
                    fluidRow(id = "content"))
    
    server <- function(input, output, session) {
      ids <- reactiveVal(0)
      kill_switch <- reactiveVal(FALSE)
      handler <- reactiveValues()
    
      add_new <- function() {
        kill_switch(FALSE)
        ids(ids() + 1)
        new_id <- paste0("id", ids())
        insertUI("#content", "beforeEnd", boxer_ui(new_id))
        handler[[new_id]] <- callModule(boxer, new_id, kill_switch)
      }
    
      observeEvent(input$new, {
        isolate({
          add_new()
        })})
    
      observeEvent(input$add5, {
        isolate({
          kill_switch(TRUE)
          replicate(5, add_new())
        })})
    
      observeEvent(input$killall, kill_switch(TRUE))
    }
    
    shinyApp(ui, server)
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   thothal    6 年前

    我能想到的一个解决办法是分裂 remove / add 如下:

    server <- function(input, output, session) {
      ids <- reactiveVal(0)
      kill_switch <- reactiveVal(FALSE)
      add5 <- reactiveVal(FALSE)
    
      handler <- reactiveValues()
    
      add_new <- function() {
        kill_switch(FALSE)
        ids(ids() + 1)
        new_id <- paste0("id", ids())
        insertUI("#content", "beforeEnd", boxer_ui(new_id))
        handler[[new_id]] <- callModule(boxer, new_id, kill_switch)
      }
    
      observeEvent(input$new, {
        isolate({
          add_new()
        })})
    
      observeEvent(input$add5, {
        isolate({
          kill_switch(TRUE)
          add5(TRUE)
        })})
    
      observe({
          req(add5())
          isolate({
             replicate(5, add_new())
             add5(FALSE)
          })
      })
    
      observeEvent(input$killall, kill_switch(TRUE))
    }
    

    然而,这是基于以下假设: observer 不会被任何其他人打断 观察者 . 是真的吗?在这种情况下,我还可以补充 priority 确保内部 观察者 先开枪。

    有人能证实我的假设是正确的吗?