从使用insertUI创建的模块获取输入

时间:2019-03-18 10:03:12

标签: r module shiny

在我的应用程序中,我将使用class Employee: def __init__(self, Name, Wage = 0, Hours = 0, Admin = False, code = ''): self.Name = Name self.Wage = Wage self.Hours = Hours self.Admin = Admin self.code = code def calcweeklywages(Employee, totalhours): '''Return the total weekly wages for a worker working totalHours, with a given regular hourlyWage. Include overtime for hours over 40. ''' hourlywage = Employee.Wage if totalhours <= 40: totalwages = hourlywage * totalhours else: overtime = totalhours - 40 totalwages = hourlywage * 40 + (1.5 * hourlywage) * overtime return totalwages # In your main body, you just test the functionality EmployeeList = [] EmployeeList.append(Employee("Anne", 34)) EmployeeList.append(Employee("Johnathan", 30)) EmployeeList.append(Employee("Mr. Admin", 50, 0, True, 'Open Sesame')) while(True): action = int(input('Enter action :\n 1. Exit.\n 2. Add new employee.\n 3. Compute weekly wage\n')) if(action == 1): break elif(action == 2): AdminName = input('Enter operator name : ') Flag = False for EmployeeInst in EmployeeList: if((EmployeeInst.Name == AdminName) & (EmployeeInst.Admin)): code = input('Enter code :') if(code != EmployeeInst.code): break NewName = input('New Employee name? :') NewWage = int(input('New employee wage? :')) EmployeeList.append(Employee(NewName, NewWage)) Flag = True if(not Flag): print('Wrong Credentials') break elif(action == 3): name = input('Enter the employee\'s name: ') for Employee in EmployeeList: if(Employee.Name == name): Person = Employee hours = int(input('Enter the number of hours worked: ')) print('Wages for', hours, 'hours at', Person.Wage,'per hour is', calcweeklywages(Person, hours)) else: print('Input out of range') break 动态创建一个模块。我试图找到一种捕获该模块输出的方法。在下面的应用程序中,有一个简单的模块,其中包含一个insertUI元素。服务器部分返回此textInput元素的值并报告它是活动的。我正在尝试捕获此返回值。

我试图创建一个textInput对象来获取模块的输出,但是当输入改变时,该对象似乎没有更新。模块代码本身正在运行,因为我收到了来自模块内部的消息,但是检查reactiveValues的外部观察命令仅在重新创建它们时才执行。如何从模块外部获取这些值

reactiveValues

1 个答案:

答案 0 :(得分:2)

这里的问题很简单:您需要显式地将值作为反应式返回。 return(reactive(input$text))

通过仅返回input$text,您实际上只是在某个时间点返回它,因为input$text只是一个值。通过将其包装在reactive()中,您现在将返回一个反应表达式。服务器代码必须与之匹配,因此我在访问该值的代码中添加了()

我删除了“简单测试”,因为它导致错误,因为该模块最初不存在。

library(shiny)

# a module that only has a text input
moduleUI = function(id){
  ns = NS(id)
  tagList(
    # the module is enclosed within a div with it's own id to allow it's removal
    div(id = id,
        textInput(ns('text'),label = 'text'))
  )
}

# the module simply returns it's input and reports when there is a change
module = function(input,output,session){
  observeEvent(input$text,{
    print('module working')
  })
  return(reactive(input$text))
}


# ui is iniated with add/remove buttons
ui = fluidPage(
  actionButton('add','+'),
  actionButton('remove','-')
)

server = function(input, output,session) {
  # number of ui elements already created
  uiCount = reactiveVal(0)

  moduleOuts = reactiveValues()

  observeEvent(input$add,{
    # count the UI elements created to assign new IDs
    uiCount(uiCount()+1)
    # insert module UI before the add/remove buttons
    insertUI('#add',
             'beforeBegin',
             moduleUI(paste0("module",uiCount())))

    # failed attempt to get the output
    moduleOuts[[as.character(uiCount())]] = callModule(module,id = paste0("module",uiCount()))
  })

  observeEvent(input$remove,{
    # if remove button is pressed, remove the UI and reduce the UI count
    removeUI(
      selector = paste0("#module",uiCount())
    )
    uiCount(uiCount()-1)
  })

  # test to get all values
  observe({
    seq_len(uiCount()) %>% sapply(function(i){
      print(moduleOuts[[as.character(i)]]())
    })
  })

}


shinyApp(ui = ui, server = server)