【问题标题】:rHandsonTable module returning NULL when called from another tabPanel从另一个 tabPanel 调用时,rHandsonTable 模块返回 NULL
【发布时间】:2019-07-30 21:33:10
【问题描述】:

我有一个在使用tabPanel 的模块中使用rHandsonTableOutput (HoT) 的应用程序。虽然我可以从这个模块中获取其他数据(例如,在 selectInput 中进行的选择),但由于某种原因,我在尝试获取 HoT 数据时得到了 NULL。我做了一个非常简单的代码版本来说明我的意思。

我发现如果我将模块放在同一个 UI 元素中,则可以访问 HoT 数据。出于某种原因,如果我将它放在 tabPanel 的另一个选项卡中,它无法返回数据。我的示例代码应该在这里显示。

更新 - 我发现只要我先单击并加载带有问题的HoT 的选项卡,该模块就可以工作!首先“查看”选项卡似乎可以解决这个问题。我很想找到一种不需要这样做的方法。这与 rshiny “会话”有关吗?

下面是应该重现错误的代码。您会发现一个包含两个HoTs 的简单应用程序。主选项卡有一个通过模块myModuleUI 放入。第二个下拉选项卡包含通过第二个模块myModuleTabUI 生成的第二个HoT。除了myModuleTabUI 将所有内容都放在tabPanel 中之外,它们是相同的。如果您按下“添加表格按钮”,它只会将表格中的数字相加,但在尝试为 ID first_tabHoT(即在另一个中找到的HoT)时会失败标签)。


这包含主要的闪亮应用

application.R

library(shiny)
library(rhandsontable)

source('my_modules.R')

ui <- navbarPage("Module Test Tool",

             tabsetPanel(id = 'mainTabset',
                         tabPanel("My Tab",

                                  #This is the HoT that is accessible from a module
                                  h4("Table 1"),
                                  myModuleUI('my_module'), 
                                  br(),
                                  br(),

                                  fluidRow(
                                    actionButton("sum_btn", "Add table data"),
                                    br(),
                                    br(),
                                    textOutput('table1_sum'),
                                    textOutput('table2_sum'),
                                    br(),
                                    br()
                                  )
                         ),
                         navbarMenu("My Module Tabs",
                                    #This is the HoT that is inaccessible from a module
                                    myModuleTabUI('first_tab', 'First')

                         )
             )

)


server <- function(input, output, session) {

  #Link logic for tab module
  callModule(myModule, 'my_module')
  callModule(myModuleTab, 'first_tab')

  one_col = rep.int(1,3)
  df = data.frame(col1 = one_col,
                  col2 = one_col,
                  col3 = one_col)

  output$hot <- renderRHandsontable({
    rhandsontable(df, stretchH = "none", rowHeaders = NULL)
  })


  #This button sums up all the rHandsonTable data frames
  observeEvent(input$sum_btn, {

    #Works just fine when not pulling from the same panel's module
    module_data = callModule(getMyModuleData, 'my_module')
    module_int= module_data$module_int
    module_df = module_data$module_hot

    output$table1_sum = renderText({
      paste0("Sum of Table 1 is: ", sum(module_df)," | Integer one is: ", module_int)
    })

    #Fails when pulling a hands on table from another tab
    module_tab_data = callModule(getMyModuleTabData, 'first_tab') #<---THIS LINE FAILS
    module_tab_int= module_tab_data$module_tab_int
    module_tab_df = module_tab_data$module_tab_hot 

    output$table2_sum = renderText({
      paste0("Sum of the table in the 'First' tab is: ", sum(module_tab_df)," | Integer in 'First' tab is: ", module_tab_int)
    })

  })


}

## Create Shiny app ----
shinyApp(ui, server)

此文件包含此示例中使用的模块:

my_modules.R

#Simple module containing one rHandsontable and a drop down list of integers
myModuleUI <- function(id,tab_name){

  ns <- NS(id)

  fluidRow(
    rHandsontableOutput(ns("module_hot")),
    selectInput(ns('module_int_list'),"Integers:",c(1:5), selected = 1)
  )


}

#Initializes myModuleUI rHandsonTable with some values
myModule <- function(input, output, session) {

  two_col = rep.int(2,3)
  df = data.frame(col1 = two_col,
                  col2 = two_col,
                  col3 = two_col)

  output$module_hot <- renderRHandsontable({
    rhandsontable(df, stretchH = "none", rowHeaders = NULL)
  })
}

#Returns myModule data for use outside of the module
getMyModuleData <- function(input,output,session){
  return (
      list(
        module_hot = hot_to_r(input$module_hot),
        module_int = input$module_int_list
    )
  )
}

#Simple module that adds the same as MyModuleUI, except in a tabPanel
myModuleTabUI <- function(id,tab_name){

  ns <- NS(id)

  tabPanel(tab_name,
           fluidRow(
             rHandsontableOutput(ns("module_tab_hot")),
             selectInput(ns('module_tab_int_list'),"Integers:",c(1:5), selected = 1)
           )
  )

}

#Initializes myModuleTabUI rHandsonTable with some values
myModuleTab <- function(input, output, session){

  three_col = rep.int(3,3)
  df = data.frame(col1 = three_col,
                  col2 = three_col,
                  col3 = three_col)

  output$module_tab_hot <- renderRHandsontable({
    rhandsontable(df, stretchH = "none", rowHeaders = NULL)
  })

}

#Returns MyModuleTab data for use outside of the module
getMyModuleTabData <- function(input,output,session){
  return (
    list(
      module_tab_hot = hot_to_r(input$module_tab_hot), #<---THIS LINE FAILS
      module_tab_int = input$module_tab_int_list
    )
  )
}

【问题讨论】:

    标签: r module shiny rhandsontable


    【解决方案1】:

    请编辑这些行:

    #Fails when pulling a hands on table from another tab
    module_tab_dat = callModule(getMyModuleTabData, 'first_tab') #<---THIS LINE FAILS
    module_tab_int= module_tab_dat$module_tab_int
    module_tab_df = module_tab_dat$module_tab_hot
    

    你有:

    module_tab_int= module_data$module_tab_int
    module_tab_df = module_data$module_tab_hot 
    

    但是您将模块命名为 module_tab_dat。我假设复制粘​​贴错误。

    更新

    关于您的更新,请在您的模块代码中添加这一行:

    output$module_tab_hot <- renderRHandsontable({
        rhandsontable(df, stretchH = "none", rowHeaders = NULL)
      })
    # Added line
    outputOptions(output, "module_tab_hot", suspendWhenHidden = FALSE)
    

    suspendWhenHidden 恰如其分地命名为TRUE,默认情况下这对于大多数用例来说可能是正确的。在这种情况下,它必须是FALSE。见here

    【讨论】:

    • 好收获!是的,这是一个复制粘贴错误。感谢您的观看!
    • 要清楚,这不是错误的来源!错误仍然存​​在。
    • 您将其编辑为 module_tab_data。其实就是module_tab_dat。
    • Eli,如果您在不先单击选项卡的情况下运行应用程序,它是否有效?仅当我首先单击“第一个”选项卡时单击“添加表数据”按钮才对我有用。如果我不这样做,我会收到错误消息。就好像我必须在“第一个”选项卡中“看到”或加载有问题的 rHandsonTable 才能成功。
    • 我刚刚看到你的更新。我现在将研究那篇文章。我似乎误解了你的问题。
    猜你喜欢
    • 2020-08-02
    • 2020-06-07
    • 1970-01-01
    • 2017-12-02
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    相关资源
    最近更新 更多