0Pricing
R Academy · Ders

Kod Yeniden Kullanımı için Shiny Modülleri

Kullanıcı arayüzü ve sunucu mantığını ad alanlı, yeniden kullanılabilir modüller içinde kapsülleyin.

Kod Yeniden Kullanımı için Shiny Modülleri, CoddyKit'te ücretsiz bir R Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, R Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. R Academy kursu toplamda 4 dersten oluşur.

Shiny Modülleri Neden Kullanılır?

Shiny uygulamaları büyüdükçe, tüm kullanıcı arayüzü ve sunucu kodunu tek bir dosyada tutmak yönetilemez hâle gelir. Modüller, ad alanlarına sahip kimlikler kullanan, kendi içinde bütünleşik Shiny kullanıcı arayüzü ve sunucu mantığı parçalarıdır. Aynı modülü bir uygulamada kimlik çakışmaları olmadan birden çok kez yeniden kullanabilir ve modülleri bağımsız olarak sınayabilirsiniz.

# Problem: without modules, ID conflicts arise
# ui <- fluidPage(
#   selectInput('dataset', ...),  # used by plot1 AND plot2!
#   selectInput('dataset', ...)   # duplicate ID — BROKEN
# )

# With modules: each instance has its own namespaced IDs
# plotModule('plot1', ...)  ->  input$plot1-dataset
# plotModule('plot2', ...)  ->  input$plot2-dataset

NS() — Ad Alanı İşlevi

Her modül kullanıcı arayüzü işlevi ns <- NS(id) ile başlar. Shiny'ye aktarılan tüm kullanıcı arayüzü öğesi kimlikleri ns() içine alınmalıdır. Bu işlev her kimliğin başına id- ekleyerek modül örnekleri arasındaki çakışmaları önleyen bir ad alanı oluşturur.

# Module UI function
filter_plot_ui <- function(id) {
  ns <- NS(id)  # create the namespace function

  tagList(
    selectInput(ns('dataset'), 'Choose Dataset:',
                choices = c('mtcars', 'iris', 'airquality')),
    sliderInput(ns('n_rows'), 'Rows to show:', 1, 50, 20),
    plotOutput(ns('scatter_plot'))
  )
}

moduleServer() — Sunucu İşlevi

moduleServer(id, function(input, output, session) {...}), modül sunucu mantığını tanımlamanın modern (Shiny 1.5 ve sonrası) yoludur. İşlev içinde input, output ve session otomatik olarak ad alanına alınır; input$plot1-dataset yerine input$dataset kullanarak erişirsiniz.

# Module server function
filter_plot_server <- function(id) {
  moduleServer(id, function(input, output, session) {

    data <- reactive({
      # input$dataset is already namespaced to this instance
      head(get(input$dataset), input$n_rows)
    })

    output$scatter_plot <- renderPlot({
      df <- data()
      plot(df[[1]], df[[2]],
           xlab = names(df)[1], ylab = names(df)[2])
    })
  })
}

Uygulamada Modülleri Kullanma

Modül kullanıcı arayüzü işlevini ui içinde, modül sunucu işlevini ise server içinde çağırın; her ikisinde de aynı id dizesini kullanın. Bağımsız örnekler oluşturmak için aynı modülü farklı kimliklerle birden çok kez çağırabilirsiniz.

# Main app using the module twice
ui <- fluidPage(
  h2('Plot 1'),
  filter_plot_ui('plot1'),   # instance 1
  hr(),
  h2('Plot 2'),
  filter_plot_ui('plot2')    # instance 2 — no ID conflicts!
)

server <- function(input, output, session) {
  filter_plot_server('plot1')  # wire up instance 1
  filter_plot_server('plot2')  # wire up instance 2
}

shinyApp(ui, server)

Modül Kullanıcı Arayüzüne Parametre Aktarma

Modül kullanıcı arayüzü işlevleri, normal R işlevleridir. Her örneğin görünümünü veya davranışını oluşturulma sırasında özelleştirmek için id dışında ek parametreler ekleyin. Bu parametreler kullanıcı arayüzü oluşturulurken bir kez değerlendirilir.

# Module UI with extra parameters
summary_table_ui <- function(id, title = 'Summary', height = '300px') {
  ns <- NS(id)
  tagList(
    h4(title),
    div(
      style = paste0('height:', height, '; overflow-y: auto;'),
      DTOutput(ns('tbl'))
    )
  )
}

# Use with custom titles
summary_table_ui('train_tbl', title = 'Training Data', height = '400px')
summary_table_ui('test_tbl',  title = 'Test Data',     height = '200px')

Modüle Reaktif Değerleri FROM Aktarma

Modül sunucu işlevleri, parametre olarak reaktif değerleri veya ifadeleri kabul edebilir. Bu sayede üst uygulama verileri alt modüllere aktarabilir. Modül içinde, mevcut değerini almak için reaktif değeri bir işlev gibi çağırın.

# Module that accepts a reactive as input
chart_module_server <- function(id, data_reactive) {
  moduleServer(id, function(input, output, session) {
    output$chart <- renderPlot({
      df <- data_reactive()   # call the reactive passed in
      ggplot2::ggplot(df, ggplot2::aes(x = x, y = y)) +
        ggplot2::geom_point(colour = input$colour)
    })
  })
}

# In main server:
server <- function(input, output, session) {
  shared_data <- reactive({ load_data(input$source) })
  chart_module_server('chart1', data_reactive = shared_data)
  chart_module_server('chart2', data_reactive = shared_data)
}

Modülden Reaktif Değerleri RETURN Etme

Modül sunucu işlevleri, reaktif değerleri üst uygulamaya döndürebilir. Bu, alt modüllerin üst katmanla iletişim kurmasını sağlar. moduleServer() işlevinden bir reaktif değer veya reaktif değerler listesi döndürün ve bunu üst sunucu işlevinde alın.

# Module that returns a reactive to the parent
filter_module_server <- function(id, all_data) {
  moduleServer(id, function(input, output, session) {

    # Return the filtered data reactive
    filtered <- reactive({
      all_data[all_data$group == input$group_filter, ]
    })

    return(filtered)  # parent can use this reactive
  })
}

# In main server:
server <- function(input, output, session) {
  raw_data <- reactive({ read.csv('data.csv') })

  # filtered_data is a reactive returned from the module
  filtered_data <- filter_module_server('filter1', raw_data)

  output$main_plot <- renderPlot({ plot(filtered_data()) })
}

Modül Dosyalarını Düzenleme

Büyük uygulamalarda her modülü R/ klasöründe kendine ait bir dosyaya yerleştirin. Shiny, uygulama yüklenirken R/ içindeki tüm dosyaları otomatik olarak kaynak olarak yükler. Bu yaklaşım, her modülün kendi içinde bütünleşik kalmasını ve shinytest2 paketi kullanılarak bağımsız şekilde sınanabilmesini sağlar.

# Recommended project structure:
# myapp/
#   app.R                   # main app: source modules + wire up
#   R/
#     mod_filter_plot.R     # filter_plot_ui() + filter_plot_server()
#     mod_summary_table.R   # summary_table_ui() + summary_table_server()
#     mod_download.R        # download_ui() + download_server()
#   tests/
#     testthat/test-mod_filter_plot.R

# In app.R:
library(shiny)
# source('R/mod_filter_plot.R')  # not needed if in R/ folder
ui     <- fluidPage(filter_plot_ui('p1'))
server <- function(input, output, session) { filter_plot_server('p1') }
shinyApp(ui, server)

İç İçe Modüller

Modüller başka modüller içerebilir. Üst modül, session bağımsız değişkenini kullanarak kendi session ad alanını alt modül çağrılarına aktarır. İç içe geçmenin her düzeyi bir ad alanı ön eki daha ekler: outer-inner-element_id.

# Outer module uses an inner module
outer_server <- function(id) {
  moduleServer(id, function(input, output, session) {

    # Call an inner module using this module's session
    inner_result <- inner_module_server(
      id      = 'inner',
      session = session  # passes the namespaced session
    )

    output$combined <- renderText({
      paste('Inner result:', inner_result())
    })
  })
}

# ID chain: outer -> inner
# Full ID: outer-inner-element

shinytest2 ile Modülleri Sınama

shinytest2 paketi, modülleri en küçük bir uygulama içine alarak otomatik sınamalar yazmanızı sağlar. Gerçek bir tarayıcı oturumu olmadan tarayıcıyı yönetmek, girdileri ayarlamak ve çıktı değerlerini doğrulamak için AppDriver kullanın.

library(shinytest2)

# Wrap the module in a testable app
test_that('filter_plot module filters correctly', {
  test_app <- shinyApp(
    ui     = fluidPage(filter_plot_ui('test')),
    server = function(input, output, session) {
      filter_plot_server('test')
    }
  )

  app <- AppDriver$new(test_app)
  app$set_inputs('test-dataset' = 'iris')  # namespaced input
  app$wait_for_idle()

  # Assert plot was rendered
  expect_true(!is.null(app$get_value(output = 'test-scatter_plot')))
})

Modüller Arası İletişim Örüntüleri

Modüller ile üst uygulama arasındaki iletişim örüntülerinin özeti:

  • Üst Uygulamadan Modüle: reaktif değeri modül sunucusuna parametre olarak aktarın.
  • Modülden Üst Uygulamaya: moduleServer() işlevinden reaktif değer döndürün.
  • Kardeş Modüller Arasında: üst modül paylaşılan durumu (reactiveValues) tutar ve her modüle aktarır.
  • Genel Durum: üst modülde tanımlanan reactiveValues öğesini kullanın ve başvuruları alt modüllere aktarın.
# Sibling module communication via parent state
server <- function(input, output, session) {
  shared <- reactiveValues(selected_row = NULL)

  # Table module sets the selection
  table_module_server('tbl', shared_state = shared)

  # Detail module reads the selection
  detail_module_server('detail', shared_state = shared)

  # Both modules communicate through 'shared' reactiveValues
  # Table sets shared$selected_row; Detail reads it
}

Kısa Kontrol

Bir modül kullanıcı arayüzü işlevindeki tüm kullanıcı arayüzü öğesi kimlikleri neden ns() ile sarılmalıdır?

Shiny Modüllerinin Özeti

Kod Yeniden Kullanımı için Shiny Modülleri bölümünden temel çıkarımlar:

  • Modüller, tüm kimlikleri NS(id) ile ad alanına alarak kimlik çakışmalarını önler.
  • Modül kullanıcı arayüzü: ns <- NS(id) içeren normal işlev; tüm kimlikleri ns() ile sarın.
  • Modül sunucusu: moduleServer(id, function(input, output, session) {...}).
  • Reaktif değerleri işlev parametreleri olarak modüllere aktarın; üst katmanla iletişim için reaktif değerleri RETURN edin.
  • Bağımsız örnekler için aynı modülü farklı kimliklerle birden çok kez çağırın.
  • Modülleri R/mod_*.R dosyalarında düzenleyin; Shiny, R/ klasörünü otomatik olarak kaynak olarak yükler.
  • Modülleri shinytest2::AppDriver ile sınayın.
# Complete module example
my_module_ui <- function(id) {
  ns <- NS(id)
  tagList(selectInput(ns('var'), 'Variable:', choices = names(mtcars)),
          plotOutput(ns('hist')))
}

my_module_server <- function(id, data) {
  moduleServer(id, function(input, output, session) {
    output$hist <- renderPlot(hist(data()[[input$var]]))
  })
}

# Use it:
ui <- fluidPage(my_module_ui('m1'), my_module_ui('m2'))
server <- function(input, output, session) {
  d <- reactive(mtcars)
  my_module_server('m1', d)
  my_module_server('m2', d)
}
shinyApp(ui, server)

Sıkça Sorulan Sorular

“Kod Yeniden Kullanımı için Shiny Modülleri” dersi ücretsiz mi?

Evet — “Kod Yeniden Kullanımı için Shiny Modülleri” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve R Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. R Academy kursu toplamda 4 dersten oluşur.

“Kod Yeniden Kullanımı için Shiny Modülleri” dersinde ne öğreneceğim?

Kullanıcı arayüzü ve sunucu mantığını ad alanlı, yeniden kullanılabilir modüller içinde kapsülleyin. R Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

R Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te R Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“Kod Yeniden Kullanımı için Shiny Modülleri” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu R Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her R Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Tepkisel Programlamaya Derinlemesine Bakış
  2. Kod Yeniden Kullanımı için Shiny Modülleri
  3. renderUI ve insertUI ile Dinamik Kullanıcı Arayüzü
  4. Shiny Uygulamalarını Dağıtma
← R Academy Sayfasına Dön