Ich verwende eine HTML-Vorlage für eine Shiny-Anwendung und versuche, die tabPanel
-Funktionalität von Dashboards basierend auf der Fragment-ID des URI zu replizieren.
Speziell für eine Anzahl von Nav-Links, die als Seitenanker dienen, möchte ich, Shiny diese Fragment-ID, aktualisieren Sie alle serverseitigen Objekte nach Bedarf, und geben Sie die Ausgabe, die Pseudo-Registerkarte entspricht der Benutzer angeklickt auf. Dies basiert auf Joe Chengs college scorecard application (einfach die Abfragezeichenfolge für den Seitenanker austauschen). Ich würde diese Route auch lieber nicht mit einer Abfragezeichenfolge verwenden, da die App einen größeren Datensatz mit einer großen Anzahl von benutzerdefinierten Auswahlen erstellt, die in der URI codiert werden müssten. Da jede neue Suche eine Seitenaktualisierung auslöst, wäre dies wahrscheinlich eine nicht sehr gute Benutzererfahrung, wenn die Daten bei jeder Änderung der Eingaben erneut geladen, vorverarbeitet usw. werden.
Das Problem in I ausgeführt habe, ist, dass Shiny speichert nur der anfänglichen URI-Hash in session$clientData
und es gibt keine Möglichkeit, die ich gefunden habe, um das zu aktualisieren zu zwingen (mit invalidateLater
, eventReactive
oder observeEvent
), wenn der Benutzer navigiert von #summary
bis #bleep
bis #blorp
. Hat jemand schon einmal auf ein ähnliches Problem gestoßen? Oder ist es möglich, das Objekt session$clientData
ohne eine Aktualisierung der Seite zu aktualisieren?
Die andere Möglichkeit besteht darin, dem CSS einfach eine neue Klasse mit display: none;
für versteckte divs hinzuzufügen und ein wenig JS zu schreiben, um die Dinge zu behandeln. Idealerweise würde ich jedoch lieber eine Shiny-basierte Lösung finden.
Mein Code sieht ähnlich aus wie:
index.html:
...
<header role="banner">
<h3 class="usa-display">My header!</h3>
<ul>
<li><a class="nav active" href="#summary">Summary</a></li>
<li><a class="nav" href="#blorp">Another Tab</a></li>
</ul>
</header>
<div data-display-if="output.appMode === 'summary' ">
{{ renderVerbatimText("clientInfo") }}
</div>
<div data-display-if="output.appMode === 'blorp' ">
<img src="assets/img/failWhale.jpg" />
</div>
...
ui.R:
function(req) {
htmlTemplate(
"www/index.html"
)
}
server.R:
parseHashString <- function (str, nested = FALSE) {
if (is.null(str) || nchar(str) == 0) {
values <- "summary"
return(values)
}
if (substr(str, 1, 1) == "#") {
str <- substr(str, 2, nchar(str))
}
values <- strsplit(str, "#", fixed = TRUE)[[1]]
values <- values[!is.na(values)]
values <- values[values %in% c("summary", "blorp")]
return(values[1])
}
shinyServer(function(input, output, session) {
output$appMode <- reactive({
parseHashString(session$clientData$url_hash_initial)
})
outputOptions(output, "appMode", suspendWhenHidden = FALSE)
output$clientInfo<- renderText({
cdata <- session$clientData
cnames <- names(cdata)
allvalues <- lapply(cnames, function(name) {
paste(name, cdata[[name]], sep=" = ")
})
paste(allvalues, collapse = "\n")
})
})