R Shine 如何知道何时更新输入?

jer*_*roe 5 r shiny

我今天在 R Shiny 中为复选框组实现了一个切换按钮,我遇到了一些我不完全理解的有趣的事情。我创建切换按钮的第一种方法是编写一个 javascript 脚本来切换复选框的checked属性,因此当用户单击按钮时,true 变为 false,false 变为 true。这有效,当我运行闪亮的应用程序并按下切换按钮时,复选框被翻转。但是,如果我显示选择,使用renderText(),shiny 不会对我的更改做出反应。但是,如果我单击复选框组之一,Shiny 将更新为相应的复选框。

然后我更改了我的 javascript 代码,而不是设置checked属性,它使用 jQuery.click()来单击每个复选框。这种方法与我希望的完全一样,所以当我按下切换按钮时,复选框会翻转并更新文本。我很想知道为什么会这样。我的怀疑是,shiny 侦听单击事件,但无法侦听以编程方式更改的属性。我的解释不太好,所以我创建了一个小的Shinyapps 应用程序来演示切换按钮行为的差异。第一个切换按钮使用.click()和工作,第二个使用checked属性并且不会被动更新。我用来演示差异的代码如下:

用户界面

library(shiny)

fruit = c("apple", "banana", "orange", "pear", "peach")

shinyUI(fluidPage(
  tags$script(src = "toggle_button.js"),

  titlePanel("Test"),

  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("fruit_list",
                  "Select a fruit",
                  choices = fruit,
                  selected = fruit),

      fluidRow(
        actionButton("toggleButton_1", "Toggle 1"),
        actionButton("toggleButton_2", "Toggle 2")
      )

    ),

    mainPanel(
      textOutput("string")
    )
  )
))
Run Code Online (Sandbox Code Playgroud)

服务器

library(shiny)

shinyServer(function(input, output) {

  output$string <- renderText({
    paste(input$fruit_list, sep = ", ")
  })

})
Run Code Online (Sandbox Code Playgroud)

www/toggle_button.js

$(document).ready(function() {
    $("#toggleButton_1").click(function() {
      var fruit_boxes = $("#fruit_list :checkbox");

      for (var i = 0; i < fruit_boxes.length; i++) {
          fruit_boxes[i].click();
      }
    });

    $("#toggleButton_2").click(function() {
      var fruit_boxes = $("#fruit_list :checkbox");

      for (var i = 0; i < fruit_boxes.length; i++) {
          fruit_boxes[i].checked = !fruit_boxes[i].checked;
      }
    });
});
Run Code Online (Sandbox Code Playgroud)

Dea*_*ali 4

如果您有兴趣深入了解闪亮的 javascript 的工作原理,一个很好的资源是如何构建自定义输入对象

阅读完该内容并学习如何编写输入后,您将了解复选框输入的代码。具体看一下这个subscribe函数:它告诉 javascript 调用闪亮的“嘿,我刚刚更新了!” 当“更改”事件被触发时。这就是您的答案:当您手动单击输入(或使用 jqueryclick实现类似的结果)时,会触发更改事件,但是当您只是手动更改值时,不会触发该事件。

您可以通过添加自己的更改回调来测试这一点,并查看更改事件仅通过单击触发,而不是通过手动值更改触发。为了更进一步,这意味着您可以通过调用手动告诉shiny更新该值$(".checkbox").trigger("change")。尝试在更改 value 后添加该行,现在它可以工作了(虽然我不会这样做,但出于说明目的)