r-shiny 在同一回调中将多个 json 文件发送到 javascript 前端(ag-grid)
r-shiny send multiple json files to javascript frontend (ag-grid) in the same callback
我正在学习 R shiny,使用没有包装器的 AG-GRID javascript 组件,使前端和后端之间的通信成为可能,目前一切正常。
前端将 editable 网格中的每个更改发送到后端,后端将使用
在数据库上执行相同的事务
function onCellValueChanged(params) {
Shiny.setInputValue("inputID",params.data, {priority: "event"})
}
但是现在我试图在启动时不仅将网格数据从后端发送到前端,而且还尝试为使用下拉列表格式化的列发送动态计算的值列表。计算它的代码不在这里,因为它在这个例子中并不是真正必要的,但很容易我会在开始时提供服务,并且在每个 onCellValueChanged 一个新列表只包含尚未设置的值(因此用户可以只设置它们每 table).
一次
但是我不明白如何从后端使用
提供 2 个不同的文件(我已经发送的网格数据和初始列表),而不是一个
session$sendCustomMessage("jsondata1",dataJSON1)
并使用
从后端收听它们
Shiny.addCustomMessageHandler("jsondata1", function(myconstruct))
因为它适用于单个 json 文件,但我无法对其中的 2 个文件应用相同的概念。
我试过像
这样捆绑请求
session1-send-griddata
session2-send-dropdownlist
end
end
但它没有用,而且感觉不对。
下面是一个非常基本的例子:
library(shiny)
library(RSQLite)
library(DBI)
library(tidyverse)
library(jsonlite)
###################
#### JAVSCRIPT ####
###################
myscript <-'
$(document).ready(function () {
//here I just have 1 input parameter to have it working, but I would need to add a second parameter once I am able to retrieve the values for mycol2
function gridOptions(rowData) {
return {
columnDefs: [
{ field: "COL1" },
{ field: "COL2",
cellEditor: "agRichSelectCellEditor",
cellEditorPopup: true,
//this needs to be parametrised
cellEditorParams: { values: ["Value 1", "Value 2", "Value 3"]} },
],
defaultColDef: {
flex: 1,
editable: true,
},
rowData: rowData,
enableRangeSelection: true,
enableFillHandle: true,
undoRedoCellEditing: true,
undoRedoCellEditingLimit: 5,
enableCellChangeFlash: true,
onCellValueChanged: onCellValueChanged,
};
}
const gridDiv = document.querySelector("#myGrid");
Shiny.addCustomMessageHandler("jsondata1", function(rowData) {
//here I just have 1 input parameter to have it working, but I would need to add a second parameter once I am able to retrieve the values for mycol2
new agGrid.Grid(gridDiv, gridOptions(rowData));
});
});'
myjson <- '[
{
"COL1": 1,
"COL2": "Value 1"
},
{
"COL1": 2,
"COL2": "Value 2"
}
]'
###################
#### START DB ####
###################
con <- dbConnect(RSQLite::SQLite(), ":memory:")
start <- as.data.frame(fromJSON(myjson))
dbWriteTable(con, "requests", start)
dbReadTable(con, "requests")
###################
#### START APP ####
###################
ui <- fluidPage(
tags$head(
tags$script(src = "https://unpkg.com/ag-grid-enterprise/dist/ag-grid-enterprise.min.js")
),
tags$script(myscript),
div(id = "myGrid", style="height: 300px; ", class="ag-theme-alpine")
)
server <- function(input, output, session) {
data <- dbReadTable(con, "requests")
dataJSON1<-toJSON(data)
col2val <- '[{"Value 1", "Value 2", "Value 3"}]'
# here I am sending the main grid data, but I would also like to send col2val to define the possible values for the dropdown in col2
session$sendCustomMessage("jsondata1",dataJSON1)
}
shinyApp(ui = ui, server = server)
dbDisconnect(con)
您可以使用列表。
session$sendCustomMessage("jsondata1", list(rowData = dataJSON1, x = what_you_want))
Shiny.addCustomMessageHandler("jsondata1", function(message) {
// do something with message.x
new agGrid.Grid(gridDiv, gridOptions(message.rowData));
});
我正在学习 R shiny,使用没有包装器的 AG-GRID javascript 组件,使前端和后端之间的通信成为可能,目前一切正常。
前端将 editable 网格中的每个更改发送到后端,后端将使用
在数据库上执行相同的事务function onCellValueChanged(params) {
Shiny.setInputValue("inputID",params.data, {priority: "event"})
}
但是现在我试图在启动时不仅将网格数据从后端发送到前端,而且还尝试为使用下拉列表格式化的列发送动态计算的值列表。计算它的代码不在这里,因为它在这个例子中并不是真正必要的,但很容易我会在开始时提供服务,并且在每个 onCellValueChanged 一个新列表只包含尚未设置的值(因此用户可以只设置它们每 table).
一次但是我不明白如何从后端使用
提供 2 个不同的文件(我已经发送的网格数据和初始列表),而不是一个session$sendCustomMessage("jsondata1",dataJSON1)
并使用
从后端收听它们Shiny.addCustomMessageHandler("jsondata1", function(myconstruct))
因为它适用于单个 json 文件,但我无法对其中的 2 个文件应用相同的概念。
我试过像
这样捆绑请求session1-send-griddata
session2-send-dropdownlist
end
end
但它没有用,而且感觉不对。
下面是一个非常基本的例子:
library(shiny)
library(RSQLite)
library(DBI)
library(tidyverse)
library(jsonlite)
###################
#### JAVSCRIPT ####
###################
myscript <-'
$(document).ready(function () {
//here I just have 1 input parameter to have it working, but I would need to add a second parameter once I am able to retrieve the values for mycol2
function gridOptions(rowData) {
return {
columnDefs: [
{ field: "COL1" },
{ field: "COL2",
cellEditor: "agRichSelectCellEditor",
cellEditorPopup: true,
//this needs to be parametrised
cellEditorParams: { values: ["Value 1", "Value 2", "Value 3"]} },
],
defaultColDef: {
flex: 1,
editable: true,
},
rowData: rowData,
enableRangeSelection: true,
enableFillHandle: true,
undoRedoCellEditing: true,
undoRedoCellEditingLimit: 5,
enableCellChangeFlash: true,
onCellValueChanged: onCellValueChanged,
};
}
const gridDiv = document.querySelector("#myGrid");
Shiny.addCustomMessageHandler("jsondata1", function(rowData) {
//here I just have 1 input parameter to have it working, but I would need to add a second parameter once I am able to retrieve the values for mycol2
new agGrid.Grid(gridDiv, gridOptions(rowData));
});
});'
myjson <- '[
{
"COL1": 1,
"COL2": "Value 1"
},
{
"COL1": 2,
"COL2": "Value 2"
}
]'
###################
#### START DB ####
###################
con <- dbConnect(RSQLite::SQLite(), ":memory:")
start <- as.data.frame(fromJSON(myjson))
dbWriteTable(con, "requests", start)
dbReadTable(con, "requests")
###################
#### START APP ####
###################
ui <- fluidPage(
tags$head(
tags$script(src = "https://unpkg.com/ag-grid-enterprise/dist/ag-grid-enterprise.min.js")
),
tags$script(myscript),
div(id = "myGrid", style="height: 300px; ", class="ag-theme-alpine")
)
server <- function(input, output, session) {
data <- dbReadTable(con, "requests")
dataJSON1<-toJSON(data)
col2val <- '[{"Value 1", "Value 2", "Value 3"}]'
# here I am sending the main grid data, but I would also like to send col2val to define the possible values for the dropdown in col2
session$sendCustomMessage("jsondata1",dataJSON1)
}
shinyApp(ui = ui, server = server)
dbDisconnect(con)
您可以使用列表。
session$sendCustomMessage("jsondata1", list(rowData = dataJSON1, x = what_you_want))
Shiny.addCustomMessageHandler("jsondata1", function(message) {
// do something with message.x
new agGrid.Grid(gridDiv, gridOptions(message.rowData));
});