我无法在observeEvent调用中更新列表。
该列表称为Participants
,是列表列表 - 即每个用户的配置文件。任何用户都应在某个Participants
电话上更新observeEvent
。
我已尝试使变量具有反应性且非反应性,但它不起作用。
以下是最低工作示例
用户代码
library(shiny)
shinyUI( fluidPage(
sidebarLayout(
#---------------------------------------------------
# accept user transid
sidebarPanel(
numericInput("transid", "Transid", 0),
actionButton("accept", "Accept" )
),
#---------------------------------------------------
# Return user spreadsheet
mainPanel( verbatimTextOutput("userSpreadSheet"))
))
)
服务器的代码 #------------------------------------------------- - ################## #definition 库(有光泽)
## Create Participant List
ParticipantsDF <- data.frame(
Name=stringi::stri_rand_strings(n=20, length=8, pattern="[a-z]"),
ID=paste0("JA",1:20) )
spreadsheet <- list(data.frame(foo=1:10, bar=runif(10), transid=NA) )
Participants <- apply( ParticipantsDF, 1, function(e){
c( as.list(e), spreadsheet=spreadsheet ) })
ParticipantIDs <- ParticipantsDF$ID
ParticipantNames <- ParticipantsDF$Name
## Update Participants by changing a person
## based on user input of transid value
## change persons sublist named ``transid''
update_person <- function(transid, pid, participants){
## Which User
userProfile_u <- participants[[pid]]
## Update User next transid to TRUE
rows_vacant <- is.na(userProfile_u$spreadsheet$transid)
row_update <- head( which(rows_vacant),1)
userProfile_u$spreadsheet[row_update, "transid"] <- TRUE
## Update Participants
participants[[pid]] <- userProfile_u
Participants <<- participants
}
#----------------------------------------------------------------------
##################
# Server
server <- function( input, output, session){
#---------------------------------------------------
# Get authorized user: requires shiny-server-pro
user <- session$user
#---------------------------------------------------
# Return user profile
userPID <- which(ParticipantIDs == session$user )
userProfile <- Participants[[userPID]]
#---------------------------------------------------
# When user clicks ``accept'', update Participants
observeEvent(input$accept, {
update_person(
input$transid,
userPID,
Participants
)
})
#---------------------------------------------------
# Display spreadsheet to user
## Does Not Update!
output$userSpreadSheet <- renderPrint({
Participants[[userPID]][["spreadsheet"]] })
## Updates (Based on Accepted Answer)
#ReactiveParticipants <- reactiveValues(Participants=Participants)
#output$userSpreadSheet <- renderPrint({
# ReactiveParticipants$Participants[[userPID]][["spreadsheet"]]
#})
#observe({ invalidateLater(100)
# ReactiveParticipants$Participants <<- Participants
#})
}
shinyServer(server)
如果我编辑上面的代码不使用renderPrint reactiveValues,那么它仍然无效。
答案 0 :(得分:0)
看起来反应可能存在一些问题。据我所知,session$user
在应用程序运行时(对于该用户)不会改变,因此反应语句及其依赖关系可能根本不会执行第二次(这就是为什么最后一个部分不会更新)
第二部分我不确定isolate
如何在Participants
上工作,因为这是全局环境中的静态变量,而不是反应对象。您是否可以提供完全可重现的代码?
编辑:
您的示例实际上非常接近,主要问题是您尝试在观察者(renderPrint
)中读取静态全局变量。由于您的函数update_person
在将参与者保存到全局环境时也返回参与者,您可以直接将其用作reactiveValue然后调用它:
server <- function(input, output, session){
#---------------------------------------------------
# Get authorized user: requires shiny-server-pro
user <- session$user
#---------------------------------------------------
# Return user profile
userPID <- which(ParticipantIDs == user )
userProfile <- Participants[[userPID]]
rv <- reactiveValues(Participants = Participants)
observeEvent(input$accept, {
rv$Participants <- update_person(
input$transid,
userPID,
Participants
)
})
output$userSpreadSheet <- renderPrint({
rv$Participants[[userPID]][["spreadsheet"]]
})
}
我希望它有所帮助。