Shiny CRUD 在 golem 模块中不起作用(但在简单的 shiny 应用程序中工作)

Shiny CRUD not working in golem module (but working in simple shiny app)

提问人:TT95F 提问时间:12/6/2022 最后编辑:Jason AllerTT95F 更新时间:12/8/2022 访问量:87

问:

我已经改编了一些 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
    })

下一部分是添加一个有效的项目,因此它不会在下面添加,然后编写代码以删除模态

JavaScript 闪亮 的命名空间 DT Golem

评论

0赞 Stéphane Laurent 12/7/2022
我不明白,因为你的代码不完整。首先,你的 HTML 代码中缺少引号:应该是 .现在对于您的问题,替换为可以解决问题吗?否则,请发布一个最小的可重复示例。onclick=get_id(this.id)onclick="get_id(this.id)"x %>% ......ns(x) %>% .....
0赞 TT95F 12/8/2022
谢谢你,但它没有用。我刚刚添加了大部分模块代码。
0赞 Stéphane Laurent 12/8/2022
这并非最低限度。
0赞 TT95F 12/8/2022
我不明白如何制作一个最小的傀儡示例,所以我剪掉了一些块。希望现在更清楚了。

答: 暂无答案