應用的格式和啓動
你也許注意到了,Shiny應用的定義和啓動方式有不止一種。有的時候你會在server.R文件裏看到shinyServer(),同樣也會在ui.R文件裏看到shinyUI()。有的時候卻根本找不到server.R文件。
本文概述了定義和啓動Shiny應用的不同方法。
server.R和ui.R文件
大多數早期的Shiny樣例中會包含一個server.R文件和一個ui.R文件,比如下面這個:
## server.R ##
function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
})
}
## ui.R ##
fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
)
對於以這種方式定義的應用,server.R文件必須返回一個server函數,ui.R文件必須返回一個UI對象(本例中的UI對象是由fluidPage()創建的)。換句話說,如果文件中包含其他代碼(比如公共函數(utility function)),你就必須保證這個文件最後的語句是server函數或者UI對象。
要想更深入的瞭解這方面內容,請參看這個關於 雙文件應用 的文章。
shinyServer()和shinyUI()
對於Shiny 0.10之前的版本,server.R和ui.R分別需要調用shinyServer()和shinyUI()。稍早的Shiny應用樣例看起來也許會是下面這樣。它們其實和之前的例子是一樣的,只有一點,在下面的例子裏,代碼被放在shinyServer()和shinyUI()裏了:
## server.R ##
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
})
})
## ui.R ##
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
))
至於Shiny 0.10之後的版本,就不需要再這樣做了。
app.R
Shiny 0.10.2版本就可以在一個文件裏創建應用了——app.R,這個文件同時包含了UI和server代碼。它必須返回一個由shinyApp()函數創建的對象。
## app.R ##
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
This method is more appropriate for smaller applications; for larger applications, you may find that having separate ui.R
and server.R
files makes your code easier to manage.
這個辦法對於體量較小的應用更爲合適;對於體量較大的應用,使用雙文件(ui.R和server.R)會更方便。
session和clientData(參數)
在一些樣例的server代碼中,你也許會看到這樣的代碼:
function(input, output) { .... }
在其他的一些例子裏,你也許會在server function裏看到第三個叫做session的參數:
function(input, output, session) { .... }
這個session參數是可選的,僅當你想要使用高級Shiny特性的時候才使用它——有些Shiny函數會將session變量當作一個參數。
同樣地,你也許在一些舊樣例中看到server function把clientData當作參數。clientData提供了連接和web頁面上元素可見性的信息(詳見 clientdata)。
但是現在已經不需要clientData這個參數了,因爲你可以通過session的session$clientData參數實現同樣的功能。爲了代碼的連貫性,我們推薦你使用session$clientData參數。
# These two server functions do the same thing
# 這兩個server functions 的功能是一樣的
# Using the clientData argument directly (older examples)
# 直接使用clientData參數(舊例)
function(input, output, clientData) {
output$txt <- renderPrint({
clientData
})
}
# Using the session argument
# 使用session參數
function(input, output, session) {
output$txt <- renderPrint({
session$clientData
})
}
調用runApp()的方法
這幾樣東西也許會在啓動一個應用的時候被傳輸到runApp()中。
App目錄
如果你的應用在目錄 myapp/ 下,你可以這樣啓動它:
runApp("myapp")
Shiny app對象
如果你在控制檯使用shinyApp()創建了一個app對象,你可以將這個對象傳給runApp():
# Create app object (assume ui and server are defined above)
app <- shinyApp(ui, server)
runApp(app)
此外,如果你只是在控制檯寫下應用然後按回車鍵,R一樣會啓動這個應用。這是因爲當你在控制檯運行代碼的時候,R會調用print()來顯示返回值,對於Shiny app對象,print()方法會調用runApp()。所以你可以這樣來啓動應用:
app <- shinyApp(ui, server)
app
list(ui,server)
另一個啓動應用的方法是傳遞給runApp()一個包含ui和server組件的列表(list)。這是上面的Shiny app對象方法的舊形式。
# (Assume ui and server are defined above)
runApp(list(ui, server))