r - 使用闪亮的 URL 书签恢复输入值并重新运行计算
问题描述
所以我有一个闪亮的应用程序的用例,用户可以在其中输入一些值,当点击运行时,它会运行一个模型并在表中显示值。现在,当我单击书签时,它会捕获输入值。当我点击恢复书签时,它会填充输入值。我想要做的是在它恢复输入值之后,它还应该再次运行模型并填充表中的值。简而言之,恢复书签应填充值并单击运行按钮以运行模型。如何实现?
下面是书签的代码:
library(shiny)
library(RSQLite)
library(data.table)
ui <- function(request) {
fluidPage(
DT::dataTableOutput("x1"),
column(
12,
column(3,tags$div(title="forecast", numericInput("budget_input", label = ("Total Forecast"), value = 2))),
column(2, textInput(inputId = "description", label = "Bookmark description", placeholder = "Data Summary")),
column(2, bookmarkButton(id="bookmarkBtn"))),
column(2, actionButton("opt_run", "Run")),
DT::dataTableOutput("urlTable", width = "100%"),
tags$style(type='text/css', "#bookmarkBtn { width:100%; margin-top: 25px;}")
)
}
server <- function(input, output, session) {
con <- dbConnect(RSQLite::SQLite(), "bookmarks.db", overwrite = FALSE)
myBookmarks <- reactiveValues(urlDF = NULL)
observeEvent(input$bookmarkBtn, {
session$doBookmark()
})
observeEvent(input$opt_run, {
output$x1 = renderDT(df %>% mutate(Current = as.numeric(Current)*(input$budget_input)), selection = 'none', editable = TRUE)
})
if(dbExistsTable(con, "Bookmarks")){
tmpUrlDF <- data.table(dbReadTable(con, "Bookmarks"))
myBookmarks$urlDF <- tmpUrlDF[, Timestamp := as.POSIXct(Timestamp, origin="1970-01-01 00:00")]
} else {
myBookmarks$urlDF <- NULL
}
session$onSessionEnded(function() {
tmpUrlDF <- isolate({myBookmarks$urlDF})
if(!is.null(tmpUrlDF)){
dbWriteTable(con, "Bookmarks", tmpUrlDF, overwrite = TRUE)
}
dbDisconnect(con)
})
setBookmarkExclude(c("bookmarkBtn", "description", "urlTable_cell_clicked", "urlTable_rows_all", "urlTable_rows_current", "urlTable_rows_selected", "urlTable_search", "urlTable_state", "urlTable_row_last_clicked"))
df <- data.table(Channel = c("A", "B","C"),
Current = c("2000", "3000","4000"),
Modified = c("2500", "3500","3000"),
New_Membership = c("450", "650","700"))
output$x1 = renderDT(df, selection = 'none', editable = TRUE)
onBookmarked(fun=function(url){
if(!url %in% myBookmarks$urlDF$URL){
if(is.null(myBookmarks$urlDF)){
myBookmarks$urlDF <- unique(data.table(Description = input$description, URL = paste0("<a href='", url, "'>", url,"</a>"), Timestamp = Sys.time(), Session = session$token, User = Sys.getenv("USERNAME")), by="URL")
} else {
myBookmarks$urlDF <- unique(rbindlist(list(myBookmarks$urlDF, data.table(Description = input$description, URL = paste0("<a href='", url, "'>", url,"</a>"), Timestamp = Sys.time(), Session = session$token, User = Sys.getenv("USERNAME")))), by="URL")
}
}
})
output$urlTable = DT::renderDataTable({
req(myBookmarks$urlDF)
myBookmarks$urlDF[User %in% Sys.getenv("USERNAME")]
}, escape=FALSE)
}
enableBookmarking(store = "url")
shinyApp(ui, server)
解决方案
我的第一直觉是您可能需要onRestore()
按照@AndrewTaylor 的建议使用。但是在尝试运行您的代码之后,很明显,这里的问题是通过简单地修复代码中的反应性来解决的。
这是您的代码,有两个小的编辑:首先, output$x1 定义了两次,所以我删除了第二个没有使用任何反应值的代码。其次,我将第一个 output$x1 移到了一个 observeEvent 之外,并使它仅在按下按钮时触发。您通常不应该在观察者内部定义输出,除非它是强制性的特殊情况,但这里的完成方式会导致不正确的反应。解决这个问题就是您所需要的。
此外,需要加载DT
和包以使代码完全可重现。dplyr
library(shiny)
library(RSQLite)
library(data.table)
library(DT)
library(dplyr)
ui <- function(request) {
fluidPage(
DT::dataTableOutput("x1"),
column(
12,
column(3,tags$div(title="forecast", numericInput("budget_input", label = ("Total Forecast"), value = 2))),
column(2, textInput(inputId = "description", label = "Bookmark description", placeholder = "Data Summary")),
column(2, bookmarkButton(id="bookmarkBtn"))),
column(2, actionButton("opt_run", "Run")),
DT::dataTableOutput("urlTable", width = "100%"),
tags$style(type='text/css', "#bookmarkBtn { width:100%; margin-top: 25px;}")
)
}
server <- function(input, output, session) {
con <- dbConnect(RSQLite::SQLite(), "bookmarks.db", overwrite = FALSE)
myBookmarks <- reactiveValues(urlDF = NULL)
observeEvent(input$bookmarkBtn, {
session$doBookmark()
})
observeEvent(input$opt_run, {
cat('HJE')
})
output$x1 <- DT::renderDataTable({
input$opt_run
isolate({
datatable(
df %>% mutate(Current = as.numeric(Current)*(input$budget_input)), selection = 'none', editable = TRUE
)
})
})
if(dbExistsTable(con, "Bookmarks")){
tmpUrlDF <- data.table(dbReadTable(con, "Bookmarks"))
myBookmarks$urlDF <- tmpUrlDF[, Timestamp := as.POSIXct(Timestamp, origin="1970-01-01 00:00")]
} else {
myBookmarks$urlDF <- NULL
}
session$onSessionEnded(function() {
tmpUrlDF <- isolate({myBookmarks$urlDF})
if(!is.null(tmpUrlDF)){
dbWriteTable(con, "Bookmarks", tmpUrlDF, overwrite = TRUE)
}
dbDisconnect(con)
})
setBookmarkExclude(c("bookmarkBtn", "description", "urlTable_cell_clicked", "urlTable_rows_all", "urlTable_rows_current", "urlTable_rows_selected", "urlTable_search", "urlTable_state", "urlTable_row_last_clicked"))
df <- data.table(Channel = c("A", "B","C"),
Current = c("2000", "3000","4000"),
Modified = c("2500", "3500","3000"),
New_Membership = c("450", "650","700"))
onBookmarked(fun=function(url){
if(!url %in% myBookmarks$urlDF$URL){
if(is.null(myBookmarks$urlDF)){
myBookmarks$urlDF <- unique(data.table(Description = input$description, URL = paste0("<a href='", url, "'>", url,"</a>"), Timestamp = Sys.time(), Session = session$token, User = Sys.getenv("USERNAME")), by="URL")
} else {
myBookmarks$urlDF <- unique(rbindlist(list(myBookmarks$urlDF, data.table(Description = input$description, URL = paste0("<a href='", url, "'>", url,"</a>"), Timestamp = Sys.time(), Session = session$token, User = Sys.getenv("USERNAME")))), by="URL")
}
}
})
output$urlTable = DT::renderDataTable({
req(myBookmarks$urlDF)
myBookmarks$urlDF[User %in% Sys.getenv("USERNAME")]
}, escape=FALSE)
}
enableBookmarking(store = "url")
shinyApp(ui, server)
推荐阅读
- reactjs - React Typescript - 添加自定义属性
- r - 如何将 RFE 选择的变量插入到 r 中的机器学习模型中?
- javascript - 无法停止使用 javascript 录制
- javascript - 使用 javascript 表达式返回基于文件扩展名的文件列表
- xpath - 谷歌表格中的 Importhtml 公式用于网络抓取
- javascript - 你如何使 this.forceUpdate() 应用于 React Native 中的整个应用程序?
- apache-flink - 什么是 blobstore 文件,为什么它们会不断填满 /tmp 目录?
- excel - 如何遍历包含字符串的列的行并通过电子邮件发送这些字符串?
- typescript - 我将如何在 TypeScript 中进行动态转换的 C++ 等价?
- regex - 用正则表达式匹配第二次出现