如何跳过链接模式方法(shinyalert 库)中的元素?

How to skip elements in chaining modal approach (shinyalert library)?

我在 shinyalert 中打破循环的问题已解决

我决定尝试“链接模式”方法。

这种方法似乎适用于我的情况,但我面临另一个问题- 因为我没有使用任何循环,所以值不再用作参数(未使用向量“all.elements”)。
在我的例子中,这有点问题,因为在我原来的应用程序中,要检查的“元素”是预先选择的,只有一部分矢量元素应该包含在“shinyalert”部分中。
出于这个原因,我想保留之前选择的元素的“元素向量”。不包含在向量中的元素应在模态链中跳过(在示例中应跳过元素“C”,这意味着“你接受元素 C 吗?”消息不应弹出,即使元素“A”和“B” " 之前已被用户确认)。
App 应该从“你接受元素 B 吗?”开始到“你接受元素D吗?”直接提问
我试图在我的 shinyalert 中使用 ifelse 函数来实现这一点,但我没有成功。

有办法吗?在我使用“链接模式”方法编写的代码下方。

library(shiny)
library(shinyalert)

ui <- fluidPage(
    actionButton("run", "Run")
)

server <- function(input, output, session) {

observeEvent(input$run, {
    
    all.elements <- c("A", "B", "C", "D", "E")
    selected.elements <- c("A", "B", "D", "E")
    
    shinyalert(
        title = "Do you accept element A?",
        showCancelButton =  TRUE,
        callbackR = function(value) {
            ifelse(value == TRUE,
                   shinyalert(title = "Do you accept element B?",
                              showCancelButton =  TRUE,
                              callbackR = function(value) {
                                  ifelse(value == TRUE, shinyalert(title = "Do you accept element C?",
                                                                   showCancelButton =  TRUE,
                                                                   callbackR = function(value) {
                                                                       ifelse(value == TRUE, shinyalert(title = "Do you accept element D?",
                                             showCancelButton =  TRUE, callbackR = function(value) {
                                                 ifelse(value == TRUE,
                                                        shinyalert(title = "Do you accept element E?",
                                                                   showCancelButton =  TRUE), decision <<- "STOP")}), decision <<- "STOP")}), decision <<- "STOP")}), decision <<- "STOP")}
    )
})
}

shinyApp(ui = ui, server = server)

我注意到的另一件事是,当我快速单击“确定”时,有时不会出现连续的消息。 也许有一种方法可以使用 Shiny 中内置的模态方法来做类似的事情,而不使用 shinyalert 库?

改用shinyWidgets::confirmSweetAlert。我之前在 shinyalert chaining 中注意到了这个错误,你需要让作者修复它。相反,我总是使用 shinyWidgets 的 sweetalert。此外,当回调链很长时,它看起来非常难看。它被称为回调地狱:http://callbackhell.com/.

看下面我是如何用confirmSweetAlert

解决问题的
library(shiny)
library(shinyWidgets)

ui <- fluidPage(
    actionButton("run", "Run")
)

server <- function(input, output, session) {
    observeEvent(input$run, {
        all.elements <- c("A", "B", "C", "D", "E")
        selected.elements <- c("A", "B", "D", "E")
        confirmSweetAlert(session, "comfirmA", "Do you accept element A")
    })
    
    observeEvent(input$comfirmA, {
        req(input$comfirmA)
        confirmSweetAlert(session, "comfirmB", "Do you accept element B")
    })
    
    observeEvent(input$comfirmB, {
        req(input$comfirmB)
        confirmSweetAlert(session, "comfirmC", "Do you accept element C")
    })
    
    observeEvent(input$comfirmC, {
        req(input$comfirmC)
        confirmSweetAlert(session, "comfirmD", "Do you accept element D")
    })
    
    observeEvent(input$comfirmD, {
        req(input$comfirmD)
        confirmSweetAlert(session, "comfirmE", "Do you accept element E")
    })
}

shinyApp(ui = ui, server = server)

好的,回到你的问题,我们如何自动做链并跳过一些项目。

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
    actionButton("run", "Run")
)

server <- function(input, output, session) {
    all.elements <- c("A", "B", "C", "D", "E")
    selected.elements <- c( "B", "D", "E")
    excluded_index <- which(!all.elements %in% selected.elements)
    comfirm_text <- c(
        "Do you accept element A",
        "Do you accept element B",
        "Do you accept element C",
        "Do you accept element D",
        "Do you accept element E"
    )
    
    observeEvent(input$run, {
        confirmSweetAlert(session, paste0("comfirm", selected.elements[1]), comfirm_text[-excluded_index][1])
    })

    lapply(seq_along(selected.elements)[2:length(selected.elements)], function(x) {
        observeEvent(input[[paste0("comfirm", selected.elements[x -1])]], {
            req(input[[paste0("comfirm", selected.elements[x -1])]])
            confirmSweetAlert(
                session, 
                paste0("comfirm", selected.elements[x]), 
                comfirm_text[-excluded_index][x]
            )
        })
    })

}

shinyApp(ui = ui, server = server)

  1. 预生成要在每个模式上显示的所有文本。
  2. 找出排除元素的索引,我们将使用它来删除文本元素中的项目。
  3. 当按钮被点击时,我们触发第一个selected.elements
  4. 使用循环创建 selected.elements 从 2 到结束的链。