Shiny学习笔记:响应式编程-1

简介
前面主要学习的是用户前段UI,现在开始将学习服务端,这是用户不可见的Shiny部分,Shiny服务端利用的是响应式编程(Reactive Programming),这是一种优美的、强大的编程范式,但是也是容易让人迷惑的。Reactive Programming的核心是指定从属关系,当输出变化时,所有与其相关的输出将自动变化。这使得Shiny App变得流畅。
server()函数
一个Shiny App的框架如下:
library(shiny)
ui <- fluidPage(
# front end interface
)
server <- function(input, output, session) {
# back end logic
}
shinyApp(ui, server)
UI相对来说是很简单的,所有用户看到都是同样的前端界面,但是server端不一样,每个的用户都需要一份app拷贝,不同用户之间互不干扰。
为了实现这种独立性,Shiny在每一个session启动的时候会调用一次server()函数。当server()函数被调用的时候,会创建一个独立的本地环境,这可以保证每一个session都有其独一无二的状态,可以隔离函数内部创建的变量,所以你会发现几乎所有的reactive programming都是在server()函数内部。
server()函数有三个参数:input、output、session。
Input
input类似于一个list,包含用户在浏览器传递的数据,举个例子,如果UI含有一个数值输入count:
ui <- fluidPage(
numericInput("count", label = "Number of values", value = 100)
)
那么你获取的数据就是input$count,它的初始值为100, 当用户改变值的时候,input$count值自动同步改变。input是只读对象,如果在server()函数内部修改input会报错:
server <- function(input, output, session) {
input$count <- 10
}
shinyApp(ui, server)
#> Error: Attempted to assign value to a read-only reactivevalues object
input会有选择性地允许谁可以读取它,要读取input中的值,必须是由renderText(),reactive()等类似函数创建的reactive context。
server <- function(input, output, session) {
message("The value of input$count is ", input$count)
}
shinyApp(ui, server)
#> Error: Operation not allowed without an active reactive context.
#> (You tried to do something that can only be done from inside
#> a reactive expression or observer.)
Output
与input类似,区别是output传递输出,input接收输入。output往往是与render函数一起。
ui <- fluidPage(
textOutput("greeting")
)
server <- function(input, output, session) {
output$greeting <- renderText("Hello human!")
}
render函数做两件事:
- 它指定了
output与对应的input - 将
R代码转化为HTML