如何在R Shiny应用程序中将变量从模块返回到服务器?

时间:2018-05-16 18:19:46

标签: r module shiny

我在R Shiny应用程序中将变量从模块返回到服务器时遇到了惊人的困难。在一个模块中,我想在按下按钮时返回一个值,所以我将return()语句包装在observeEvent()内的一个块中。但是,不返回所需的值,整个observeEvent()块似乎是。

我试图创建一个最小的工作示例,概述下面的问题:

ui.R

# ui.R

fluidPage(
  input_module_ui("input"),
  actionButton("print_input_button",
               label = "Print Input")
)

server.R

# server.R

function(input, output, session) {

  # Calling input module.
  input_module_return <- callModule(input_module, "input")

  observeEvent(input$print_input_button, {
    print(input_module_return)
  })

}

global.R

# global.R

source("modules/input.R")

input.R

# input.R

input_module_ui <- function(id) {

  ns <- NS(id)

  tagList(
    textInput(ns("text_input"),
              label = h2("Input Text:")),
    actionButton(ns("submit_input"),
                 label = "Submit Input")
  )

}

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

  print("I should only print once")

  observeEvent(input$submit_input, {
    print("Return input")
    return(input$text_input)
  })

}

测试此应用时,我在文本输入框中输入“test”并提交输入。但是,当我尝试打印输入时,而不是按照我的预期打印“测试”,打印出以下内容:

<Observer>
  Public:
    .autoDestroy: TRUE
    .autoDestroyHandle: function () 
    clone: function (deep = FALSE) 
    .createContext: function () 
    .ctx: environment
    destroy: function () 
    .destroyed: FALSE
    .domain: session_proxy
    .execCount: 3
    .func: function () 
    initialize: function (observerFunc, label, suspended = FALSE, priority = 0, 
    .invalidateCallbacks: list
    .label: observeEvent(input$submit_input)
    .onDomainEnded: function () 
    onInvalidate: function (callback) 
    .onResume: function () 
    .prevId: 1896
    .priority: 0
    resume: function () 
    run: function () 
    self: Observer, R6
    setAutoDestroy: function (autoDestroy) 
    setPriority: function (priority = 0) 
    suspend: function () 
    .suspended: FALSE

我认为这对应于input.R中的最后一个块:

observeEvent(input$submit_input, {
    print("Return input")
    return(input$text_input)
  })

如何让此应用按预期工作,并在观察到input$text_input时返回input$submit_input

1 个答案:

答案 0 :(得分:3)

你非常接近让这个工作。闪亮模块的技巧是将变量传入和传出它们需要将变量作为反应值传递。我对你的代码进行了两处小改动,以获得我认为你希望看到的东西。

首先是从服务器模块返回public void setAlarm(long timeInMillis){ if(Build.VERSION.SDK_INT >= 23){ mCalendar.set( mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.DAY_OF_YEAR), mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE) ); } final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, MyAlarm.class); intent.setData(currentUri); final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); alarmManager.setExact(AlarmManager.RTC, timeInMillis, pendingIntent); 的被动版本(而不是从观察者本身返回,这应该告诉应用程序你想要发生什么):

input$text_input

第二个变化是,input_module <- function(input, output, session) { print("I should only print once") observeEvent(input$submit_input, { print("Return input") }) return(reactive({input$text_input})) } 的输出现在是被动的。如果您需要值而不是函数内容,则需要使用input_module来解析对象。所以,在你的服务器功能中:

()

输出:

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

  # Calling input module.
  input_module_return <- callModule(input_module, "input")

  observeEvent(input$print_input_button, {
    print(input_module_return())
  })

}