rhinoverse系列

  1. rhinoverse系列-rhino包
  2. rhinoverse系列-shiny.router包

在网页设计和开发中,路由(Routing)是指确定用户在浏览器中访问不同页面(URL)时,应该加载哪些页面内容(UI)过程。其优点包括(1)允许单页面应用,无需一次性加载全部页面;(2)页面之间的流畅切换,不会感到明显的延迟等

image-20240406220356561

1
2
3
install.packages("shiny.router")
packageVersion("shiny.router")
# [1] ‘0.3.1’

1. 基本用法

1
2
3
4
5
6
7
8
9
# ui part
router_ui(
    route(path, ui) 
    # path: url的路径
    # ui:一套UI组件(div()/tagList()),或者模块Module的UI部分 
)

# server part
router_server(root_page = "/")  # 默认router_ui的首页为"/"

由于是page-level配置,router_ui()/router_server()一般用于main.R或者app.R,而不用于模块中。

  • 如下的例子,设计了两个路由映射,分别是/(根目录)与anoter,对应两个UI组件;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
library(shiny)
library(shiny.router)

home_page <- div(
  titlePanel("Home page"),
  p("This is the home page!")
)
another_page <- div(
  titlePanel("Another page"),
  p("This is the another page!"),
)

ui <- fluidPage(
  router_ui(
    route("/", home_page), 			# 常规UI组件
    route("another", another_page), # 常规UI组件
    # route("another2", module_UI(ns("id"))), # shiny module
    # route("another3", module$ui(ns("id"))), # rhino module    
      
  )
)
server = function(input, output, session){
  router_server()
}

shinyApp(ui, server)
image-20240406152025711

2. 页面切换

  • route_link:在UI端实现路由页面间的切换,自动为path添加/#!/前缀来指定目标界面
1
route_link(path)  
  • 如下示例
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
library(shiny)
library(shiny.router)

home_page <- tagList(
  titlePanel("Home page"),
  p("This is the home page!"),
  a("Go to another page!", href = route_link("another"))
)
another_page <- tagList(
  titlePanel("Another page"),
  p("This is the another page!"),
  a("Go to root page!", href = route_link("/"))
)

ui <- fluidPage(
  router_ui(
    route("/", home_page),
    route("another", another_page)
  )
)
server = function(input, output, session){
  router_server()
}

shinyApp(ui, server)
image-20240406155506698
  • change_page:在Server端,通过event事件触发路由页面切换
1
change_page
  • 如下示例
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
library(shiny)
library(shiny.router)

home_page <- tagList(
  titlePanel("Home page"),
  p("This is the home page!"),
  actionButton("btn1","Click to another page!")
)
another_page <- tagList(
  titlePanel("Another page"),
  p("This is the another page!"),
  actionButton("btn2","Click to root page!")
)

ui <- fluidPage(
  router_ui(
    route("/", home_page),
    route("another", another_page)
  )
)
server = function(input, output, session){
  router_server()
  observeEvent(input$btn1, {
    change_page("another")
  })
  observeEvent(input$btn2, {
    change_page("/")
  })
}

shinyApp(ui, server)
image-20240406202109738

3. 参数URL

  • get_query_param:在路由url映射的过程中,可根据特定组件的参数值自动更新页面
1
get_query_param(field = NULL)
  • 如下示例,设置柱状图的bins数量为url的额外参数,field名为bins。
    • 一方面,可直接设置特定的http://127.0.0.1:5306/#!/another?bins=5 URL链接,修改直方图的bins数 ;
    • 另一方面,可结合change_page(),设置相应的输入控件,动态调整url。(虽然该控件可以直接对接绘图函数)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
home_page <- tagList(
  titlePanel("Home page"),
  p("This is the home page!")
)
plot_page <- tagList(
  titlePanel("Plot page"),
  p("This is the plot page!"),
  sliderInput("bins", "The number of bins:", value = 6, 
              step = 1, min = 3, max = 10),
  plotOutput("plot")
)

ui <- fluidPage(
  router_ui(
    route("/", home_page),
    route("another", plot_page)
  )
)
server <- function(input, output, session){
  router_server()
  bins <- reactive({
    bins <- get_query_param("bins")
    # e.g. http://127.0.0.1:5306/#!/another?bins=5
    if(is.null(bins)){  #初始默认值
      bins = 3
    }
    as.numeric(bins) #文本字符转数值变量
  })
  
  output$plot <- renderPlot({
    hist(mtcars$mpg, breaks = bins())
  })
  
  observeEvent(input$bins,{ #根据sliderInput自动更新url
    change_page(paste0("another?bins=", input$bins))
  })
}

shinyApp(ui, server)
image-20240406205723124

4. 404页面

  • 在输入的路由url不存在时,可通过page404()函数设置router_ui()的page_404参数,以显示个性化的404提醒界面
  • 如下例所示
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
library(shiny)
library(shiny.router)

home_page <- tagList(
  titlePanel("Home page"),
  p("This is the home page!")
)
page_404 <- tagList(
  titlePanel("None page for the given url."),
  actionButton("btn","Go to root page!")
)

ui <- fluidPage(
  router_ui(
    route("/", home_page),
    page_404 = page_404
  )
)
server = function(input, output, session){
  router_server()
  observeEvent(input$btn, {
    change_page("/")
  })
}

shinyApp(ui, server)
image-20240406211818697