Soo*_*oji 2 r shiny rhandsontable reactive
在R中使用模块时,我的反应性存在问题。如果我更新一个模块,然后尝试使用这些更新的值更新另一个模块,那么我会在更新之前获取这些值。
我已经写了一些基本代码来说明我的意思。在这里,我有一个应用程序,该应用程序更新rHandsontableOutput放置在称为的模块中的位置my_module ,然后在按下按钮时将此更新复制rHandsontableOutput到称为第二个模块module_to_update的位置。
我发现的是的第一个表my_module将更新,而不会更新module_to_update。相反,该module_to_update表将在update之前收到my_module的初始表的副本。如果我再次按下更新按钮,则一切正常。
我猜测这与我如何处理会话或响应值有关,但我没有主意。
问题:如何设置反应值和模块,以便可以在同一函数调用中对更新的模块数据运行操作?(例如,请参见observeEvent(input$update_btn, ...)下面的电话示例)
应用程序
library(shiny)
library(rhandsontable)
source('my_modules.R')
active_tab = ""
ui <- navbarPage("Module Test Tool",
tabsetPanel(id = 'mainTabset',
tabPanel("My Tab",
#This is the HoT that works as expected, updating when called upon
h4("Table 1"),
myModuleUI('my_module'),
#This is the HoT that does NOT work as expected. This HoT fails to use the updated values from 'my_module' HoT
h4("Table to be updated"),
myModuleUI('module_to_update'),
br(),
br(),
fluidRow(
#this button updates tables to new values
actionButton("update_btn", "Update and Add Tables"),
br(),
br(),
textOutput('table1_sum'),
textOutput('table2_sum'),
br(),
br()
)
)
)
)
server <- function(input, output, session) {
#Link logic for tab module
callModule(myModule, 'my_module')
#This button sums up all the rHandsonTable data frames
observeEvent(input$update_btn, {
#Update values in table and integer drop down list before doing basic operations on them
#New values should be all 5s
five_col = rep(5,3)
callModule(updateModule, 'my_module', 5, data.frame(col1 = five_col,
col2 = five_col,
col3 = five_col))
#Grabs updated module table and does operations on it
module_data = callModule(getMyModuleData, 'my_module')
module_int= module_data$module_int
module_df = module_data$module_df
output$table1_sum = renderText({
paste0("Sum of Table 1 is: ", sum(module_df())," | The selected integer is: ", module_int())
})
#------------------------------------------------------
#------------------ERROR BELOW-------------------------
#------------------------------------------------------
#THIS IS THE CODE THAT FAILS. This updates a 2nd module that should mirror the updated values. However, this results in old values.
callModule(updateModule, 'module_to_update', module_int(), module_df())
#Tries to call on new, updated table
updated_module_data = callModule(getMyModuleData, 'module_to_update')
updated_module_int= updated_module_data$module_int
updated_module_df = updated_module_data$module_df
#Display results of basic operations on new table
output$table2_sum = renderText({
paste0("Sum of Updated Table is: ", sum(updated_module_df())," | The selected integer is: ", updated_module_int())
})
})
}
## Create Shiny app ----
shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)
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) {
one_col = rep.int('VALUE AT INITIALIZATION',3)
df = data.frame(col1 = one_col,
col2 = one_col,
col3 = one_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_df = reactive({hot_to_r(input$module_hot)}),
module_int = reactive({input$module_int_list})
)
)
}
updateModule<- function(input,output,session, new_integer, new_dataframe){
if(!is.null(new_dataframe))
{
output$module_hot <- renderRHandsontable({
rhandsontable(new_dataframe, stretchH = "none", rowHeaders = NULL)
})
}
outputOptions(output, "module_hot", suspendWhenHidden = FALSE)
updateSelectInput(session, "module_int_list",selected = new_integer)
}
Run Code Online (Sandbox Code Playgroud)
这里有一些问题...
您正在使用相同的名称空间调用多个不同的模块。模块应该彼此独立运行。它们每个都应具有自己的名称空间。以下是不正确的:
callModule(myModule, 'my_module')
callModule(updateModule, 'my_module', 5, data.frame(col1 = five_col,
col2 = five_col,
col3 = five_col))
module_data = callModule(getMyModuleData, 'my_module')
Run Code Online (Sandbox Code Playgroud)
您正在从中调用模块observeEvent()。这意味着每次观察到该事件时,您都会尝试初始化该模块。您不想初始化模块,而是想将新变量传递给该模块。如果使模块返回其值,则将这些返回的值用作另一个模块的输入,则无需观察该事件……接收新信息的模块将决定是否观察该变化。
您已经创建了一个getMyModuleData仅应返回存在于其他模块中的数据的功能/ 模块。相反,您应该让另一个模块返回所需的数据。
检出:https : //shiny.rstudio.com/articles/communicate-bet-modules.html。
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |