我今天在 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)
如果您有兴趣深入了解闪亮的 javascript 的工作原理,一个很好的资源是如何构建自定义输入对象。
阅读完该内容并学习如何编写输入后,您将了解复选框输入的代码。具体看一下这个subscribe函数:它告诉 javascript 调用闪亮的“嘿,我刚刚更新了!” 当“更改”事件被触发时。这就是您的答案:当您手动单击输入(或使用 jqueryclick实现类似的结果)时,会触发更改事件,但是当您只是手动更改值时,不会触发该事件。
您可以通过添加自己的更改回调来测试这一点,并查看更改事件仅通过单击触发,而不是通过手动值更改触发。为了更进一步,这意味着您可以通过调用手动告诉shiny更新该值$(".checkbox").trigger("change")。尝试在更改 value 后添加该行,现在它可以工作了(虽然我不会这样做,但出于说明目的)