提问人:TT95F 提问时间:12/6/2022 最后编辑:Jason AllerTT95F 更新时间:12/8/2022 访问量:87
Shiny CRUD 在 golem 模块中不起作用(但在简单的 shiny 应用程序中工作)
Shiny CRUD not working in golem module (but working in simple shiny app)
问:
我已经改编了一些 CRUD 代码,这些代码在经典的闪亮应用程序中完美运行。我决定将它包含在一个傀儡模块中。但是在傀儡中,编辑和删除按钮不会启动模式窗口。
我检查了我是否遗漏了一些 ns(),但我不这么认为。我还尝试以不同的方式加载 get_id() 函数(见下文),但它什么也没改变。
我发现的唯一奇怪的线索是在浏览器开发环境中,它显示“找不到 id 为 CRUD_1-dt_table 的表”
我是 Stack Overflow 的新手。谢谢你的帮助。
请在下面找到脚本 .js 中的代码,该代码似乎已正常加载
function get_id(clicked_id) {
Shiny.setInputValue("current_id", clicked_id, {priority: "event"});
}
对于模块的 UI 部分,代码很简单
mod_CRUD_ui <- function(id){
ns <- NS(id)
tagList(
# Button to add a project -> it works
div(
class = "container",
div(
style = "margin-top: 50px;", shiny::actionButton(
inputId = ns("add_project"), label = "Ajouter un projet",
icon = shiny::icon("plus"), class = "btn-success"
)
)
),
# To display the DT table
div(
class = "container",
style = "margin-top: 50px;",
DT::DTOutput(outputId = ns("dt_table"), width = "100%")
),
shiny::includeScript(system.file("app/www", "script.js", package = "REXDI"))
# shiny::includeScript("app/www/script.js")
# tags$script(src= "script.js")
)
}
数据首先包含在 global$CRUD_init (reactiveValues) 中,当应用在另一个模块中启动时,该值被初始化
#' CRUD Server Functions
mod_CRUD_server <- function(id, global){
moduleServer( id, function(input, output, session){
ns <- session$ns
observeEvent(global$CRUD_init , {
global$CRUD_init_co <- global$CRUD_init
# the get_id() function from the script.js file is used in the next part of # the code. Normally it works
global$create_btns <- function(x) {
x %>%
purrr::map_chr(~
paste0(
'<div class = "btn-group">',
'<button class="btn btn-default action-button btn-info action_button" id="edit_',
.x, '" type="button" onclick=get_id(this.id)>
<i class="fas fa-edit"></i>
</button>
<button class="btn btn-default action-button btn-danger action_button" id="delete_',
.x, '" type="button" onclick=get_id(this.id)>
<i class="fa fa-trash-alt"></i>
</button>
</div>'
))
}
# Buttons in df global$CRUD
x <- global$create_btns(global$CRUD_init_co$id)
global$CRUD_init_co <- global$CRUD_init_co %>%
dplyr::bind_cols(tibble("Buttons" = x))
## reactiveValues global$CRUD ----
global$CRUD <- shiny::reactiveValues(
df = global$CRUD_init_co %>%
dplyr::select(-id),
dt_row = NULL,
add_or_edit = NULL,
edit_button = NULL,
keep_track_id = max(global$CRUD_init_co$id) + 1
)
})
它后面跟着函数 modal_dialog(因为它很长,我只保留了几个参数和输入
modal_dialog <- function(Projet,
Centre,
...and so forth...,
edit) {
if(edit) {
x <- "Soumettre modifications"
} else {
x <- "Ajouter un projet"
}
shiny::modalDialog(
title = "Editer un projet",
div(
class = "text-center",
div(
style = "display: inline-block;",
shiny::textInput(inputId = ns("Projet"),
label = "Projet",
value = Projet,
placeholder = "",
width = "200px")
),
div(
style = "display: inline-block;",
shiny::textInput(inputId = ns("Centre"),
label = "Centre",
value = Centre,
placeholder = "Entrer un Centre",
width = "200px")
),
...and so forth...
),
size = 'm',
easyClose = TRUE,
footer = div(
class = "pull-right container",
shiny::actionButton(inputId = ns("final_edit"),
label = x,
icon = shiny::icon("edit"),
class = "btn-info"),
shiny::actionButton(inputId = ns("dismiss_modal"),
label = "Fermer",
class = "btn-danger")
)
) %>% shiny::showModal()
}
我还尝试将 ns(“dt_table”) 添加到 DT::d ataTableProxy(“dt_table”) 中,但它不起作用,我不确定是否真正了解模块中的 dataTableProxy
## output DT ----
output$dt_table <- DT::renderDT(
{
shiny::isolate(global$CRUD$df)
},
escape = F,
rownames = FALSE,
options = list(processing = FALSE)
)
## Proxy DT ----
proxy <- DT::dataTableProxy("dt_table")
shiny::observe({
DT::replaceData(proxy, global$CRUD$df, resetPaging = FALSE, rownames = FALSE)
})
删除代码很清楚
## delete row ----
shiny::observeEvent(input$current_id, {
shiny::req(!is.null(input$current_id) &
stringr::str_detect(input$current_id,
pattern = "delete"
))
global$CRUD$dt_row <- which(stringr::str_detect(global$CRUD$df$Buttons,
pattern = paste0("\\b", input$current_id, "\\b")
))
下一段代码的目的只是为了记住已删除的内容,所以我没有将其包含在这篇文章中
然后删除
sql_id <- global$CRUD$df[global$CRUD$dt_row, ][["Buttons"]] %>%
stringr::str_extract_all(pattern = "delete_[0-9]+") %>%
unlist() %>%
readr::parse_number()
query <- stringr::str_glue("DELETE FROM TDP WHERE id = {sql_id}")
DBI::dbSendQuery(
con,
query
)
...
})
单击按钮时,编辑部分(如删除部分)不会启动。所有代码都在一个经典的闪亮应用程序中工作,我没有看到任何丢失的 ns(),所以这对我来说是一个谜
# when edit button is clicked, modal dialog shows current editable row filled out ----
shiny::observeEvent(input$current_id, {
shiny::req(!is.null(input$current_id) &
stringr::str_detect(input$current_id,
pattern = "edit"
))
global$CRUD$dt_row <- which(stringr::str_detect(global$CRUD$df$Buttons,
pattern = paste0("\\b", input$current_id, "\\b")
))
df <- global$CRUD$df[global$CRUD$dt_row, ]
modal_dialog(
### A modifier -----
Projet = df$Projet,
Centre = df$Centre,
...and so forth or else the code is too long...
edit = TRUE
)
global$CRUD$add_or_edit <- NULL
})
# when final edit button is clicked, table will be changed ----
shiny::observeEvent(input$final_edit, {
shiny::req(!is.null(input$current_id) &
stringr::str_detect(input$current_id, pattern = "edit") &
is.null(global$CRUD$add_or_edit))
global$CRUD$edited_row <- dplyr::tibble(
Projet = input$Projet,
Centre = input$Centre,
....and so forth...or else it is too long
Buttons = global$CRUD$df$Buttons[global$CRUD$dt_row]
)
sql_row <- global$CRUD$edited_row %>%
dplyr::select(-Buttons)
id <- global$CRUD$df[global$CRUD$dt_row, ][["Buttons"]] %>%
stringr::str_extract_all(pattern = "delete_[0-9]+") %>%
unlist() %>%
readr::parse_number()
# browser()
query <- paste0(
"UPDATE TDP SET ",
paste0(names(sql_row), "=", "'", unlist(c(sql_row)), "'", collapse = ", "),
stringr::str_glue("WHERE id = {id}")
)
DBI::dbSendQuery(
global$con,
query
)
global$CRUD$df[global$CRUD$dt_row, ] <- global$CRUD$edited_row
})
下一部分是添加一个有效的项目,因此它不会在下面添加,然后编写代码以删除模态
答: 暂无答案
评论
onclick=get_id(this.id)
onclick="get_id(this.id)"
x %>% ......
ns(x) %>% .....