如何根据捕获的 shinyalert 输入值打破 for 循环
How to break a for loop basing on captured shinyalert input value
我正在使用 for loop 在我闪亮的应用程序中创建多个弹出消息(使用 shinyalert包)。
如果用户单击 Cancel 作为对上一条消息的答复,我希望消息停止弹出。
下面是说明我的示例的代码示例
library(shiny)
library(shinyalert)
ui <- fluidPage(
actionButton("run", "Run")
)
server <- function(input, output, session) {
observeEvent(input$run, {
vector.elements <- c("A", "B", "C", "D", "E")
decision <<- TRUE
for (element in vector) {
shinyalert(
title = "Do you accept following element?",
text = element,
showCancelButton = TRUE,
callbackR = mycallback)
mycallback <- function(value) {
decision <<- value
}
if (decision == FALSE) {
break
}
}
})
}
shinyApp(ui = ui, server = server)
如果用户点击取消按钮作为对的回答,您是否接受以下元素? A,我希望以后的消息不要弹出
如有任何提示,我们将不胜感激!
Shiny alert 似乎 运行 与循环不同步。将 print(decision)
放在 for-loop 前面。它将在控制台中显示循环 运行s 独立于用户单击警报消息。这意味着:它不适用于 for 循环或任何其他循环。只能使用Shiny提供的事件机制来完成。
下面的解决方案创建并操作了一个反应值 RequiredAnswers
。对其进行任何更改都会触发闪亮的警报打开并要求用户确认 向量的第一个元素 RequiredAnswers
。换句话说,它删除了刚刚回答“否”的元素。
警报的每个答案都会被 observeEvent(input$AnswerAlert, {})
捕获。如果响应是“取消”,它会取消 RequiredAnswers
的第一个元素,从而触发下一个警报。这样我们就得到了一个循环。如果响应为“Ok”,它将清除 RequiredAnswers
并且不会触发更多警报(因为 observeEvent(RequiredAnswers(), {})
不响应 RequiredAnswers == NULL
.
缺点:如果用户点击 'Cancel' 速度非常快,Shiny 无法识别事件 observeEvent(input$AnswerAlert, {})
不会被调用。我不能确定这是什么来源。我的猜测是 Shiny Alert 中的一个错误。
另一种方法是递归执行(请参阅文档中的“链接模态”部分)。这样,可以避免丢失的事件。
library(shiny)
library(shinyalert)
ui <- fluidPage(
actionButton("run", "Run"),
verbatimTextOutput("answer", placeholder = TRUE)
)
server <- function(input, output, session) {
RecentDecision <- reactiveVal()
RequiredAnswers <- reactiveVal()
# Responds to the alert being confirmed or dismissed
observeEvent(input$AnswerAlert, {
if (input$AnswerAlert) {
Answer <- RequiredAnswers()[1]
RecentDecision(Answer)
print(RecentDecision())
RequiredAnswers(NULL)
} else {
# Remove the first item of RequiredAnswers
# Clear it completely when the end has been reached
if (length(RequiredAnswers()) == 1) {
RequiredAnswers(NULL)
RecentDecision(NULL)
}
else
RequiredAnswers(RequiredAnswers()[-1])
}
})
# Responds to changes, ignores NULL
observeEvent(RequiredAnswers(), {
shinyalert(
title = "Do you accept following element?",
text = RequiredAnswers()[1],
showCancelButton = TRUE,
inputId = "AnswerAlert" # use individual id
)
})
# Respond to the Run button
observeEvent(input$run, {
# Set up the vector of desired answers
RequiredAnswers(c("A", "B", "C", "D", "E"))
})
output$answer <- renderText({
if (!is.null(RecentDecision()))
RecentDecision()
else
"No answer, yet"
})
}
shinyApp(ui = ui, server = server)
我正在使用 for loop 在我闪亮的应用程序中创建多个弹出消息(使用 shinyalert包)。 如果用户单击 Cancel 作为对上一条消息的答复,我希望消息停止弹出。 下面是说明我的示例的代码示例
library(shiny)
library(shinyalert)
ui <- fluidPage(
actionButton("run", "Run")
)
server <- function(input, output, session) {
observeEvent(input$run, {
vector.elements <- c("A", "B", "C", "D", "E")
decision <<- TRUE
for (element in vector) {
shinyalert(
title = "Do you accept following element?",
text = element,
showCancelButton = TRUE,
callbackR = mycallback)
mycallback <- function(value) {
decision <<- value
}
if (decision == FALSE) {
break
}
}
})
}
shinyApp(ui = ui, server = server)
如果用户点击取消按钮作为对的回答,您是否接受以下元素? A,我希望以后的消息不要弹出
如有任何提示,我们将不胜感激!
Shiny alert 似乎 运行 与循环不同步。将 print(decision)
放在 for-loop 前面。它将在控制台中显示循环 运行s 独立于用户单击警报消息。这意味着:它不适用于 for 循环或任何其他循环。只能使用Shiny提供的事件机制来完成。
下面的解决方案创建并操作了一个反应值 RequiredAnswers
。对其进行任何更改都会触发闪亮的警报打开并要求用户确认 向量的第一个元素 RequiredAnswers
。换句话说,它删除了刚刚回答“否”的元素。
警报的每个答案都会被 observeEvent(input$AnswerAlert, {})
捕获。如果响应是“取消”,它会取消 RequiredAnswers
的第一个元素,从而触发下一个警报。这样我们就得到了一个循环。如果响应为“Ok”,它将清除 RequiredAnswers
并且不会触发更多警报(因为 observeEvent(RequiredAnswers(), {})
不响应 RequiredAnswers == NULL
.
缺点:如果用户点击 'Cancel' 速度非常快,Shiny 无法识别事件 observeEvent(input$AnswerAlert, {})
不会被调用。我不能确定这是什么来源。我的猜测是 Shiny Alert 中的一个错误。
另一种方法是递归执行(请参阅文档中的“链接模态”部分)。这样,可以避免丢失的事件。
library(shiny)
library(shinyalert)
ui <- fluidPage(
actionButton("run", "Run"),
verbatimTextOutput("answer", placeholder = TRUE)
)
server <- function(input, output, session) {
RecentDecision <- reactiveVal()
RequiredAnswers <- reactiveVal()
# Responds to the alert being confirmed or dismissed
observeEvent(input$AnswerAlert, {
if (input$AnswerAlert) {
Answer <- RequiredAnswers()[1]
RecentDecision(Answer)
print(RecentDecision())
RequiredAnswers(NULL)
} else {
# Remove the first item of RequiredAnswers
# Clear it completely when the end has been reached
if (length(RequiredAnswers()) == 1) {
RequiredAnswers(NULL)
RecentDecision(NULL)
}
else
RequiredAnswers(RequiredAnswers()[-1])
}
})
# Responds to changes, ignores NULL
observeEvent(RequiredAnswers(), {
shinyalert(
title = "Do you accept following element?",
text = RequiredAnswers()[1],
showCancelButton = TRUE,
inputId = "AnswerAlert" # use individual id
)
})
# Respond to the Run button
observeEvent(input$run, {
# Set up the vector of desired answers
RequiredAnswers(c("A", "B", "C", "D", "E"))
})
output$answer <- renderText({
if (!is.null(RecentDecision()))
RecentDecision()
else
"No answer, yet"
})
}
shinyApp(ui = ui, server = server)