2017-10-29 7 views
1

モジュールに大きく依存している光っているアプリがあります。基本的には、すべてのタブがモジュールとしてラップされている異なるメニューとタブを持つ大きなnavbarPageです。下に私は2つのタブで、最小限の例を提供していますが、サーバ機能は、このハードコーディングされたサーバ機能を非常に大きくなる参照かもしれませんが、現実には20以上R ShinyApps:ダイナミックモジュールのインポートにより、アプリケーションが間違ったタブをレンダリングする

# module 1 ------------------------------------------------ 
moduleOneUI <- function(id) { 
    ns = NS(id) 

    tagList(
    h2("module1"), 
    textOutput(ns("text")) 
) 
} 

moduleOne <- function(input, output, session) { 
    output$text <- renderText({"one yo"}) 
} 

# module 2 ------------------------------------------------ 
moduleTwoUI <- function(id) { 
    ns = NS(id) 

    tagList(
    h2("module2"), 
    textOutput(ns("text")) 
) 
} 

moduleTwo <- function(input, output, session) { 
    output$text <- renderText({"two yo"}) 
} 

# main app ------------------------------------------------ 
ui <- navbarPage(
    "dashboard", 
    navbarMenu(
    "#1", 
    tabPanel(
     "mod1", 
     uiOutput("module_one") 
    ) 
), 

    navbarMenu(
    "#2", 
    tabPanel(
     "mod2", 
     uiOutput("module_two") 
    ) 
) 
) 

server <- function(input, output, session) { 
    output$module_one <- renderUI({ 
    moduleOneUI("module_one") 
    }) 
    callModule(moduleOne, "module_one") 

    output$module_two <- renderUI({ 
    moduleTwoUI("module_two") 
    }) 
    callModule(moduleTwo, "module_two") 
} 

shinyApp(ui, server) 

があります。だから私はループを使用してより動的な方法でそれを作成しようとしました:しかし、このアプローチは期待どおりに動作しません。今度はmodule_woコードがmodule_oneタブにレンダリングされています: enter image description here

なぜこれが起こっているのか、どのように修正できますか?すべてのモジュールをレンダリングするには、本当にダイナミックなアプローチが必要です。

答えて

0

2つのrenderUIの式は、ループが完了してmod_id = "module_two"まで評価されません。

は、この問題を回避するには、各ループ反復のためlocalスコープを作成することができます。引数の `lapply`力の評価は、関数に渡されたので

for (mod_id in names(modules)) { 
    local({ 
    mod_id <- mod_id 

    module <- modules[[mod_id]] 
    ui_func <- module$ui 
    server_func <- module$server 

    output[[mod_id]] <- renderUI({ 
     ui_func(mod_id) 
    }) 

    callModule(server_func, mod_id) 
    }) 
} 
0

私はその問題の解決策を見つけたようです。モジュールを呼び出す関数を定義すると、すべてが期待通りに機能します。

create_tab <- function(mod_id, output) { 
    module <- modules[[mod_id]] 
    ui_func <- module$ui 
    server_func <- module$server 

    output[[mod_id]] <- renderUI({ 
    ui_func(mod_id) 
    }) 
    callModule(server_func, mod_id) 
} 

server <- function(input, output, session) { 
    lapply(names(modules), create_tab, output = output) 
} 

しかし、私はこれがなぜ機能しているのか分かりませんし、他のアプローチはそうではありません。 Rのスコープと関連があると仮定します。

+0

これは動作します。全ての 'apply'関数はR 3.2でこれを行うように変更されました。 –

+0

その情報をありがとう!しかし、それはまたこのようにするときにlapplyなしで動作するようです: '(mod_idの名前(モジュール)){ create_tab(mod_id、出力) }' – SaturnFromTitan

+0

'mod_id'は' renderUI'式の外で使われます。したがって、 'renderUI'式が評価されるときには、' mod_id'は対応する 'create_tab'関数環境のために既に評価されています。 –

関連する問題