2017-08-17 25 views
4

我有一个带有数据表的R Shiny应用程序。一列包含具有唯一ID的操作按钮。我想处理点击这些按钮,但不幸的是,我的事件处理代码(一个简单的打印语句)永远不会执行。看到这个自成一体的例子(app.R):R Shiny:处理数据表中的动作按钮

library(shiny) 
library(DT) 

ui <- shinyUI(
    fluidPage(
     title = "DataTable with Buttons", 
     fluidRow(
      column(
       width = 8, 
       dataTableOutput("employees") 
      ) 
     ) 
    ) 
) 

server <- shinyServer(function(input, output) { 
    df <- data.frame(
     name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'), 
     motivation = c(62, 73, 3, 99, 52), 
     stringsAsFactors = FALSE 
    ) 
    fireButtons <- list() 
    fireButtonIds <- list() 
    for (r in rownames(df)) { 
     id <- paste("fire_", r, sep = "") 
     fireButtonIds[[r]] <- id 
     button <- actionButton(id, label = "Fire") 
     fireButtons[[r]] <- as.character(button) 
    } 
    df$actions <- fireButtons 
    dt <- datatable(df, colnames = c("#", "Name", "Motivation", "Actions")) 
    output$employees <- renderDataTable(dt) 


    for (id in fireButtonIds) { 
     # binding doesn't work 
     # - is the path wrong? 
     # - is it because the button is really a string, not an object? 
     observeEvent(input$employees$x$data$actions[[id]], { 
      print(paste("click on", i)) 
     }) 
    } 
}) 

shinyApp(ui = ui, server = server) 

我看到了两个可能的问题:

  1. 我使用的路径(input$employees$x$data$actions[[id]])是错误的
  2. 的路径我使用是正确的,但是它并不指向可以实际处理的东西,即它只是一个HTML字符串而不是一个按钮对象。

或者有更好的方法将按钮放入数据表中......?

回答

7

这是否完成了你想要做的事情?

library(shiny) 
library(DT) 

shinyApp(
    ui <- fluidPage(
    DT::dataTableOutput("data"), 
    textOutput('myText') 
), 

    server <- function(input, output) { 

    myValue <- reactiveValues(employee = '') 

    shinyInput <- function(FUN, len, id, ...) { 
     inputs <- character(len) 
     for (i in seq_len(len)) { 
     inputs[i] <- as.character(FUN(paste0(id, i), ...)) 
     } 
     inputs 
    } 

    df <- reactiveValues(data = data.frame(

     Name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'), 
     Motivation = c(62, 73, 3, 99, 52), 
     Actions = shinyInput(actionButton, 5, 'button_', label = "Fire", onclick = 'Shiny.onInputChange(\"select_button\", this.id)'), 
     stringsAsFactors = FALSE, 
     row.names = 1:5 
    )) 


    output$data <- DT::renderDataTable(
     df$data, server = FALSE, escape = FALSE, selection = 'none' 
    ) 

    observeEvent(input$select_button, { 
     selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2]) 
     myValue$employee <<- paste('click on ',df$data[selectedRow,1]) 
    }) 


    output$myText <- renderText({ 

     myValue$employee 

    }) 

    } 
) 
+0

是的,它的确如此!我仍然需要完全理解代码,但它按预期工作。谢谢! –

+2

对不起,没有解释。您在服务器代码中创建的第一个函数是创建&命名输入的函数。然后,我们应用该函数在反应数据框中创建一列。该数据帧被放置在DT输出中,并显示在UI中。事件处理程序函数(observeEvent)在任何时候会触发任何select_button(我们创建的5)。在这种情况下,它会将被动值(myValue $ employee)更改为与员工的行ID名称相匹配。然后将该值传递给myText输出并在UI中呈现。希望是有道理的! – kostr

+0

如果您在同一个按钮上单击两次,这实际上并不会触发。任何修补程序? –