我正在开发一个Shiny模块,并通过Ajax使用Javascript代码生成数据表。但是当模块在Shiny应用程序中使用时,Chrome一直在说主线程上存在同步XMLHttpRequest,我无法弄清楚原因。 模块ui由Javascript代码生成,该代码具有一个数据表,列出了通过Ajax调用本地桌面应用程序的RESTful API检索的一些数据对象。 UI中有两个按钮,一个是'Refresh',单击时,ajax.reload()被调用,而另一个是'Import'按钮,它将选定的行导入Shiny应用程序。
我假设问题不是由“导入”按钮引起的,因为当页面加载时,警告消息立即显示,“导入”按钮没有被点击,加上导入过程被明确指定为使用异步调用。所以问题是由初始化数据表的初始ajax调用引起的,但我认为它应该默认使用异步调用。
有什么建议吗?谢谢!
wrapWithDocumentReady <- function(jsCode) {
return(paste0("$(document).ready(function(){", jsCode, "});"))
}
myModuleUI <- function(id) {
ns <- NS(id)
jsCode <- paste0(
# 1st to initialize the data table
"let objectTable = $('#",
ns("dataObjectTable"),
"').DataTable( {
ajax: {
url: 'http://localhost:XXXX/some_application/data',
dataSrc: ''
},
columns: [
{ name: 'name', data: 'name', title: 'Name' },
{ name: 'data_type', data: 'data_type', title: 'Data Type', visible:false },
{ name: 'id', data: 'id', title: 'ID', visible: false },
{ name: 'dimension', data: 'dimension', title: 'Dimension'},
],
select: {
style: 'single'
},
} );",
# 2nd to bind the 'Import' button with event
"$('#",
ns("importButton"),
"').click(function() {",
"
let selectedDataId = objectTable.cell('.selected', 'id:name').data();
var xmlhttp = new XMLHttpRequest();
var url = 'http://localhost:XXXX/some_application/data/'.concat(selectedDataId);
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
var dataJson = this.responseText;
Shiny.onInputChange('", ns("addDataObject"),"', dataJson);
}
}
};
xmlhttp.open('GET', url, true);
xmlhttp.send();
});",
# 3rd to bind the 'Reresh' button with event
"$('#",
ns("refreshButton"),
"').click(function() {
objectTable.ajax.reload();
});"
);
tagList(
div(tags$table(id = ns("dataObjectTable"), width="100%")),
actionButton(ns("refreshButton"), "Refresh"),
actionButton(ns("importButton"), "Import"),
tags$script(wrapWithDocumentReady(jsCode))
)
}
myModule <- function(input, output, session) {
importedData <- reactive ({
jsonStr <- input$addDataObject
if (!is.null(jsonStr)) {
# passing the data and return
} else {NULL}
})
return(importedData)
}