2016-08-23 15 views
5

मैं एक जटिल चमकदार ऐप को मॉड्यूलर करने की कोशिश कर रहा हूं जिसके लिए मेरे पास conditionalPanel है जो केवल एक निश्चित इनपुट स्थिति दिखाई देनी चाहिए।आर सशर्त मॉड्यूल और सशर्त के साथ चमकदार मॉड्यूल

इससे पहले कि मैं सब कुछ मॉड्यूलर बनाया है, इनपुट और conditionalPanel दोनों ui.R में थे, और मैं इनपुट संदर्भ कुछ इस तरह का उपयोग कर सकता है:

conditionalPanel("input.select == 'Option one'", p('Option one is selected')) 

अब जब कि मैं चीजों को modularized है, इनपुट तक पहुँचने है अधिक जटिल। मैंने सोचा कि निम्नलिखित करने का तरीका निम्नलिखित था, लेकिन यह काफी काम नहीं करता है। (यहाँ मैं एक भी स्टैंडअलोन स्क्रिप्ट में चीजों को संयोजित कर दिया):

library(shiny) 

## Module code for 'selectorUI' and 'selector' 
selectorUI <- function(id) { 
    ns <- NS(id) 
    selectizeInput(inputId = ns('select'), 
       label = 'Make a choice:', 
       choices = c('Option one', 'Option two')) 
} 

selector <- function(input, output, session) { 
    reactive(input$select) 
} 

## Main app 
ui <- shinyUI(fluidPage(
    selectorUI('id1'), 
    conditionalPanel(condition = "output.selected == 'Option one'", p('Option one is selected.')) 
)) 

server <- shinyServer(function(input, output, session) { 
    output$selected <- callModule(selector, 'id1') 
}) 

shinyApp(ui = ui, server = server) 

मुझे लगता है कि यह काम करना चाहिए, लेकिन यह नहीं है - यह केवल काम करता है अगर मैं मुख्य ui खंड में output$selected के लिए एक और संदर्भ बनाने:

ui <- shinyUI(fluidPage(
    selectorUI('id1'), 
    textOutput('selected'), ## Adding just this one line makes the next line work 
    conditionalPanel(condition = "output.selected == 'Option one'", p('Option one is selected.')) 
)) 

दुर्भाग्यवश यह textOutput('selected') के परिणाम को प्रस्तुत करने का अवांछित प्रभाव है। मैं केवल अनुमान लगा सकता हूं कि यह काम करने का कारण यह है कि यह किसी भी तरह प्रतिक्रियाशील को इस तरह से ट्रिगर करता है कि जावास्क्रिप्ट संदर्भ अकेले नहीं है।

कोई विचार है कि मुझे इस सशर्त पैनेल को ठीक से काम करने के लिए कैसे मिलना चाहिए?

.. धन्यवाद

संपादित करें: बाहर वास्तव में एक बग नहीं बदल जाता है: https://github.com/rstudio/shiny/issues/1318। नीचे अपना खुद का जवाब देखें।

लेकिन यह भी ध्यान दें कि मुझे वास्तव में स्वीकृत उत्तर में दिए गए renderUI समाधान को मेरे मूल conditionalPanel दृष्टिकोण से बेहतर पसंद है।

उत्तर

4

मॉड्यूल को कॉल करने के बाद selectizeInput की आईडी id1-select है। ,

objectName.property या objectName['property']

के बाद से वहाँ ID हम स्ट्रिंग के माध्यम से यह उल्लेख करने के लिए है में - तो दूसरी विधि जाने का रास्ता है: जावास्क्रिप्ट में वस्तु गुण तक पहुँचने के दो तरीके हैं।

conditionalPanel में हालत हो जाता है:

input['id1-select'] == 'Option one' 

पूर्ण उदाहरण:

library(shiny) 

## Module code for 'selectorUI' and 'selector' 
selectorUI <- function(id) { 
    ns <- NS(id) 
    selectizeInput(inputId = ns('select'), 
       label = 'Make a choice:', 
       choices = c('Option one', 'Option two')) 
} 

## Main app 
ui <- shinyUI(fluidPage(
    selectorUI('id1'), 
    conditionalPanel(condition = "input['id1-select'] == 'Option one'", 
        p('Option one is selected.')) 
)) 

server <- shinyServer(function(input, output, session) { 

}) 

shinyApp(ui = ui, server = server) 

संपादित करें:

यह काम करता है, लेकिन क्या यह मॉड्यूलरिटी की धारणा का उल्लंघन नहीं करता है? 'Id1-select' बनाने के लिए आपको आंतरिक रूप से उस इनपुट 'चयन' को कॉल करने के लिए मॉड्यूल के कोड को जानना होगा।

हाँ, आप सही हैं।

इस article के अनुसार, चाल आप अर्थात इस्तेमाल किया उत्पादन के लिए एक मॉड्यूल कॉल बताए $ चयनित और फिर output.selected के माध्यम से ग्राहक के पक्ष अपने मूल्य तक पहुँचने काम करना चाहिए लेकिन ऐसा नहीं है। मुझे नहीं पता क्यों ... यह शायद एक बग है। (मैं GitHub से नवीनतम चमकदार संस्करण है)

केवल एक चीज मैं के बारे में सोच सकते हैं नीचे दिए गए उदाहरण में के रूप में conditionalPanel के बजाय renderUI उपयोग करने के लिए है:

library(shiny) 
## Module code for 'selectorUI' and 'selector' 
selectorUI <- function(id) { 
    ns <- NS(id) 
    selectizeInput(inputId = ns('select'), 
       label = 'Make a choice:', 
       choices = c('Option one', 'Option two')) 
} 

selector <- function(input, output, session) { 
    reactive(input$select) 
} 

## Main app 
ui <- shinyUI(fluidPage(
    selectorUI('id1'), 
    uiOutput("dynamic1") 
)) 

server <- shinyServer(function(input, output, session) { 


    output$dynamic1 <- renderUI({ 
    condition1 <- callModule(selector, 'id1') # or just callModule(selector, 'id1')() 
    if (condition1() == 'Option one') return(p('Option one is selected.')) 
    }) 

}) 

shinyApp(ui = ui, server = server) 
+0

यह काम करता है, लेकिन क्या यह मॉड्यूलरिटी की धारणा का उल्लंघन नहीं करता है? 'Id1-select' बनाने के लिए आपको आंतरिक रूप से उस इनपुट 'चयन' को कॉल करने के लिए मॉड्यूल के कोड को जानना होगा। –

+0

हाँ, आप सही हैं - मैंने अपनी पोस्ट अपडेट की है। –

+1

मुझे लगता है कि यह वास्तव में एक बग है। मैंने इसे https://github.com/rstudio/shiny/issues/1318 पर एक अधिक न्यूनतम उदाहरण के साथ प्रस्तुत किया। मुझे 'रेंडरयूआई' समाधान वास्तव में बेहतर लगता है, क्योंकि 'सशर्त पैनेल' सामग्री को छिपाने के लिए 'डिस्प्ले: कोई भी' शैली पर निर्भर नहीं है, जबकि 'रेंडरयूआई' विधि सिर्फ खाली div देता है। आलेख के लिए धन्यवाद। –

2

बाहर कर देता है यह वास्तव में एक बग नहीं है , बस थोड़ा मुश्किल है। According to Joe Cheng,

दाएं - हम डिफ़ॉल्ट रूप से, आउटपुट मानों की गणना/प्रस्तुत नहीं करते हैं, अगर वे दिखाई नहीं दे रहे हैं। और यदि हम उनकी गणना नहीं करते हैं, तो आप शर्तों में उनका उपयोग नहीं कर सकते हैं।

आप, आप अपने server.R में इसका उपयोग कर सकते हर बार की गणना करने के एक निर्गम की स्थापना करके इस व्यवहार को बदल सकते हैं (इसी मूल्य के साथ outputId डालें):

outputOptions(output, "outputId", suspendWhenHidden = FALSE)

तो करने के लिए अपने मूल उदाहरण के साथ इस समस्या को ठीक है, हम केवल सर्वर कार्य करने के लिए है कि एक लाइन जोड़ने की जरूरत:

server <- shinyServer(function(input, output, session) { 
    output$selected <- callModule(selector, 'id1') 
    outputOptions(output, 'selected', suspendWhenHidden = FALSE) # Adding this line 
}) 
संबंधित मुद्दे