已添加类型为“…”的消息的未捕获处理程序

Uncaught handler for message of type “…” already added

本文关键字:消息 程序 处理 类型 添加      更新时间:2023-09-26

我与ShinyJavaScript一起工作。我用JavaScript扩展Shiny的功能。这样做,我使用了callbackHandlers。我用JS实现的click event观察用户输入。触发事件后,我将所需的数据发送到R,其中有一个函数处理这些数据。结果再次被发送回JS,在那里显示处理的数据。

。在我的JS侧,我有这样的内容:

for(var i = 0; i < radioButtons.length; i++) {
    radioButtons[i].onclick = function() {
        if (parseInt(this.value) === 10) {
            Shiny.onInputChange("go", this.value);
            Shiny.addCustomMessageHandler("someCallbackHandler1", function(someJson) {
                someFunction(someJson);
            });
        } else if (parseInt(this.value) === 11) {
            Shiny.onInputChange("go", this.value);
            Shiny.addCustomMessageHandler("someCallbackHandler2", function(someJson) {
                someFunction(someJson);
            });
       }  // more else if checking for the value
       ....

R这边,我这样做

observe({
if( !is.null(input$go) ) {
    if( (input$go == 10) ) {
        sendToJs1[["myJson"]] <- someFunctionIwrote(arg1, arg2, arg3, arg4)
        session$sendCustomMessage(type = "someCallbackHandler1", sendToJs1$myJson)
    } else if( (input$go == 11) ) {
        sendToJs2[["myJson"]] <- someFunctionIwrote(arg1, arg2, arg3, arg4, arg5, arg6)
        session$sendCustomMessage(type = "someCallbackHandler2", sendToJs2$myJson)
   } # more else if checking for which value gets send from js
   ....

当我点击值为10radioButton时,然后在radioButton上,值为11,然后在radioButton上再次点击值为10,我得到这个。

已添加类型为" someecallbackhandler1 "的消息的未捕获处理程序

因此JS注意到callbackHandler1已经被添加,并且不再添加它。但为了显示数据,我需要再次添加它。此外,如果输入数据发生变化,并且someFunctionIwrote(arg1, arg2, arg3, arg4)使用不同的输入数据执行,JS会做什么?当然callbackHandler1已经添加了,但是里面的是什么,从R发送到JS的结果是不同的。

我该如何处理这种情况?

我的建议是:

  1. 只定义一次javascript事件处理程序,并且在循环之外。不需要多次定义它们。一旦它们被创建,它们将持续侦听来自服务器的消息。

  2. 确保处理程序中声明的回调函数足够灵活,可以处理所有服务器响应。所以你的函数someFunction()应该能够处理来自服务器的所有可能的消息。

所以代码应该是:

// function to be called from inside the callback functions:
function someFunction(someJson){
 console.log("No matter what someJson is, I will handle them all properly!");
...
}
// set the event handlers for message from server:
Shiny.addCustomMessageHandler("someCallbackHandler1", function(someJson) {
                someFunction(someJson);
            });
Shiny.addCustomMessageHandler("someCallbackHandler2", function(someJson) {
                someFunction(someJson);
            });
// set the event handlers for radio button clicks:
for(var i = 0; i < radioButtons.length; i++) {
    radioButtons[i].onclick = function() {
        if (parseInt(this.value) === 10) {
            Shiny.onInputChange("go", this.value);
        } else if (parseInt(this.value) === 11) {
            Shiny.onInputChange("go", this.value);
       }  // more else if checking for the value