Zurück zu Fähigkeiten

build-shiny-module

pjt222
Aktualisiert Yesterday
1 Ansichten
17
2
17
Auf GitHub ansehen
Metareactaitestingdesign

Über

Diese Fähigkeit unterstützt Entwickler dabei, wiederverwendbare Shiny-Module mit ordnungsgemäßer Namensraum-Isolierung unter Verwendung von NS() zu erstellen. Sie behandelt den Aufbau von UI/Server-Paaren, die Handhabung reaktiver Werte sowie die Ermöglichung von Modulkommunikation und -verschachtelung. Nutzen Sie sie, wenn wiederverwendbare Komponenten aus wachsenden Apps extrahiert oder komplexe Logik hinter sauberen Schnittstellen gekapselt werden sollen.

Schnellinstallation

Claude Code

Empfohlen
Primär
npx skills add pjt222/agent-almanac -a claude-code
Plugin-BefehlAlternativ
/plugin add https://github.com/pjt222/agent-almanac
Git CloneAlternativ
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/build-shiny-module

Kopieren Sie diesen Befehl und fügen Sie ihn in Claude Code ein, um diese Fähigkeit zu installieren

Dokumentation

Build Shiny Module

創具正命名空間隔離、反應式溝通、可組合之可復用 Shiny UI/server 模組對。

適用時機

  • 自漸長之 Shiny 應用抽可復用組件
  • 建多處可用之 UI 小部件
  • 以潔介面封繁之反應邏輯
  • 自更小可測之單位組大應用

輸入

  • 必要:模組之旨與功能描
  • 必要:輸入/輸出之合同(模組受何返何)
  • 選擇性:模組是否嵌他模組(預設:否)
  • 選擇性:框架脈絡(golem、rhino、或 vanilla)

步驟

步驟一:定模組介面

書代碼前,定模組所受所返:

Module: data_filter
Inputs: reactive dataset, column names to filter on
Outputs: reactive filtered dataset
UI: filter controls (selectInput, sliderInput, dateRangeInput)

預期: 明之合同,指定反應輸入、反應輸出、UI 元素。

失敗時: 若介面不明,模組恐過廣。分為單責之小模組。

步驟二:創模組 UI 函

#' Data Filter Module UI
#'
#' @param id Module namespace ID
#' @return A tagList of filter controls
#' @export
dataFilterUI <- function(id) {
  ns <- NS(id)
  tagList(
    selectInput(
      ns("column"),
      "Filter column",
      choices = NULL
    ),
    uiOutput(ns("filter_control")),
    actionButton(ns("apply"), "Apply Filter", class = "btn-primary")
  )
}

要則:

  • 函名循 <name>UI 約定
  • 首參恆為 id
  • 於頂立 ns <- NS(id)
  • inputIdoutputId 皆包於 ns()
  • tagList() 以允彈性置

預期: UI 函創命名空間之輸入/輸出元素。

失敗時: 若用模組二次時 ID 碰撞,查每 ID 皆包於 ns()。常漏:renderUI()uiOutput() 內之 ID——此亦需 ns()

步驟三:創模組伺服器函

#' Data Filter Module Server
#'
#' @param id Module namespace ID
#' @param data Reactive expression returning a data frame
#' @param columns Character vector of filterable column names
#' @return Reactive expression returning the filtered data frame
#' @export
dataFilterServer <- function(id, data, columns) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns

    # Update column choices when data changes
    observeEvent(data(), {
      available <- intersect(columns, names(data()))
      updateSelectInput(session, "column", choices = available)
    })

    # Dynamic filter control based on selected column
    output$filter_control <- renderUI({
      req(input$column)
      col_data <- data()[[input$column]]

      if (is.numeric(col_data)) {
        sliderInput(
          ns("value_range"),
          "Range",
          min = min(col_data, na.rm = TRUE),
          max = max(col_data, na.rm = TRUE),
          value = range(col_data, na.rm = TRUE)
        )
      } else {
        selectInput(
          ns("value_select"),
          "Values",
          choices = unique(col_data),
          multiple = TRUE,
          selected = unique(col_data)
        )
      }
    })

    # Return filtered data as a reactive
    filtered <- eventReactive(input$apply, {
      req(input$column)
      col <- input$column
      df <- data()

      if (is.numeric(df[[col]])) {
        req(input$value_range)
        df[df[[col]] >= input$value_range[1] &
           df[[col]] <= input$value_range[2], ]
      } else {
        req(input$value_select)
        df[df[[col]] %in% input$value_select, ]
      }
    }, ignoreNULL = FALSE)

    return(filtered)
  })
}

要則:

  • 函名循 <name>Server 約定
  • 首參恆為 id
  • 餘參為反應式表達或靜值
  • moduleServer(id, function(input, output, session) { ... })
  • 伺服器內創之動態 UI 用 session$ns
  • 明返反應值

預期: 伺服器函處輸入、返反應輸出。

失敗時: 若反應值不更,查動態 UI 之輸入用 session$ns(非外之 ns)。若模組返 NULL,確 return()moduleServer() 內末表達。

步驟四:於父應用接模組

# In app_ui.R or ui
ui <- page_sidebar(
  title = "Analysis App",
  sidebar = sidebar(
    dataFilterUI("filter1")
  ),
  card(
    DT::dataTableOutput("table")
  )
)

# In app_server.R or server
server <- function(input, output, session) {
  # Raw data source
  raw_data <- reactive({ mtcars })

  # Call module — capture its return value
  filtered_data <- dataFilterServer(
    "filter1",
    data = raw_data,
    columns = c("cyl", "mpg", "hp", "wt")
  )

  # Use the module's returned reactive
  output$table <- DT::renderDataTable({
    filtered_data()
  })
}

預期: 模組於 UI 顯,其所返反應流至下游輸出。

失敗時: 若模組 UI 不渲,驗 UI 與伺服器呼間 id 字串相符。若所返反應為 NULL,查伺服器函實返值。

步驟五:組嵌模組(選)

含他模組之模組:

analysisUI <- function(id) {
  ns <- NS(id)
  tagList(
    dataFilterUI(ns("filter")),
    plotOutput(ns("plot"))
  )
}

analysisServer <- function(id, data) {
  moduleServer(id, function(input, output, session) {
    # Call inner module with namespaced ID
    filtered <- dataFilterServer("filter", data = data, columns = names(data()))

    output$plot <- renderPlot({
      req(filtered())
      plot(filtered())
    })

    return(filtered)
  })
}

要則:UI 中以 ns("inner_id") 嵌。伺服器中僅以 "inner_id" 呼——moduleServer 處命名空間之鏈。

預期: 內模組於外模組之命名空間中正渲。

失敗時: 若內模組 UI 不現,恐忘於外 UI 函中以 ns() 包內模組 ID。若伺服器溝通斷,查內模組 ID 相符(伺服器呼中無 ns())。

步驟六:隔離測模組

# Quick test app for the module
if (interactive()) {
  shiny::shinyApp(
    ui = fluidPage(
      dataFilterUI("test"),
      DT::dataTableOutput("result")
    ),
    server = function(input, output, session) {
      data <- reactive(iris)
      filtered <- dataFilterServer("test", data, names(iris))
      output$result <- DT::renderDataTable(filtered())
    }
  )
}

預期: 模組於最小測應用中正工。

失敗時: 若模組於隔離敗而於全應用工(或反),查對全域變或父會話狀態之隱依。

驗證

  • 模組 UI 函受 id 為首參且用 NS(id)
  • UI 中每輸入/輸出 ID 皆包於 ns()
  • 模組伺服器用 moduleServer(id, function(input, output, session) { ... })
  • 伺服器中動態 UI 之 ID 用 session$ns
  • 模組可實例化多次而無 ID 碰撞
  • 反應返值可為父應用存取
  • 模組於最小獨立測應用中工

常見陷阱

  • renderUI() 中忘 ns():伺服器內創之動態 UI 須用 session$ns——外之 nsmoduleServer() 內不可得
  • 傳非反應數據:隨時變之模組參須為反應式表達。傳 reactive(data)data
  • ID 失配:UI 呼中之 id 字串須與伺服器呼中之 id 完相符
  • 不返反應:若模組算父所需之物,須 return() 一反應。忘此為默錯
  • 嵌模組之命名空間:UI:ns("inner_id")。伺服器:僅 "inner_id"。混致雙包或漏前綴

相關技能

  • scaffold-shiny-app — 加模組前立應用結構
  • test-shiny-app — 以 testServer() 單元測測模組
  • design-shiny-ui — 模組 UI 之 bslib 版型與主題
  • optimize-shiny-performance — 模組內之快取與 async 模式

GitHub Repository

pjt222/agent-almanac
Pfad: i18n/wenyan-lite/skills/build-shiny-module
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

Verwandte Skills

content-collections

Meta

Diese Skill bietet eine produktionsgetestete Einrichtung für Content Collections – ein TypeScript-first-Tool, das Markdown/MDX-Dateien in typsichere Datensammlungen mit Zod-Validierung umwandelt. Verwenden Sie ihn beim Erstellen von Blogs, Dokumentationsseiten oder inhaltsstarken Vite + React-Anwendungen, um Typsicherheit und automatische Inhaltsvalidierung zu gewährleisten. Er behandelt alles von der Vite-Plugin-Konfiguration und MDX-Kompilierung bis hin zur Deployment-Optimierung und Schema-Validierung.

Skill ansehen

polymarket

Meta

Diese Fähigkeit ermöglicht es Entwicklern, Anwendungen mit der Polymarket-Prognosemärkte-Plattform zu erstellen, einschließlich API-Integration für Handel und Marktdaten. Sie bietet außerdem Echtzeit-Datenstreaming über WebSocket, um Live-Trades und Marktaktivitäten zu überwachen. Nutzen Sie sie zur Implementierung von Handelsstrategien oder zur Erstellung von Tools, die Live-Marktaktualisierungen verarbeiten.

Skill ansehen

creating-opencode-plugins

Meta

Diese Fähigkeit unterstützt Entwickler dabei, OpenCode-Plugins zu erstellen, die in über 25 Ereignistypen wie Befehle, Dateien und LSP-Operationen eingreifen. Sie bietet die Plugin-Struktur, Event-API-Spezifikationen und Implementierungsmuster für JavaScript/TypeScript-Module. Nutzen Sie sie, wenn Sie den Lebenszyklus des OpenCode KI-Assistenten mit benutzerdefinierter ereignisgesteuerter Logik abfangen, überwachen oder erweitern müssen.

Skill ansehen

sglang

Meta

SGLang ist ein hochperformantes LLM-Serving-Framework, das sich auf schnelle, strukturierte Generierung für JSON, Regex und agentenbasierte Workflows unter Verwendung seines RadixAttention-Prefix-Cachings spezialisiert. Es bietet deutlich schnellere Inferenz, insbesondere für Aufgaben mit wiederholten Präfixen, was es ideal für komplexe, strukturierte Ausgaben und Mehrfachdialoge macht. Wählen Sie SGLang gegenüber Alternativen wie vLLM, wenn Sie constrained decoding benötigen oder Anwendungen mit umfangreicher Präfix-Weitergabe entwickeln.

Skill ansehen