使用JavaScript动态设置Crosstalk过滤器默认值时,一个变量生效另一个失效的问题排查
问题原因与解决方案
这个问题的核心是JavaScript字符串字面量必须用引号包裹,你动态拼接JS代码时没给month的默认值加引号,导致JS解析出错;而year是数值类型,不需要引号就能被JS识别,所以可以正常生效。
为什么硬编码有效,动态传入无效?
- 硬编码时,你写的是
setValue("Jan",false),这里的"Jan"是JS能正确识别的字符串字面量,自然能设置默认值。 - 动态传入时,你的代码拼接后变成了
setValue(Jan,false)——JS会把Jan当成一个未定义的变量名,而不是字符串,控制台会抛出Jan is not defined的错误,导致设置失败。哪怕你把default_month硬编码为"Jan",只要拼接时没加外层引号,结果还是一样的。
解决方法:给动态字符串添加引号
只需要在拼接JS代码时,给default_year和default_month都加上双引号(数值型加引号也没问题,JS会自动转换类型),确保JS把它们当成字符串处理。
修改后的完整可运行代码
library(leaflet) library(crosstalk) library(geosphere) library(htmltools) dat<-data.frame(year=c(rep(2015,15),rep(2016,15),rep(2017,15)), month=factor(rep(c('Jan','Feb','Mar'),3), levels=c('Jan','Feb','Mar')), lon=randomCoordinates(n = 45)[,1], lat=randomCoordinates(n = 45)[,2]) sd <- SharedData$new(dat) dropdown_filter <- filter_select( id = "year_filter", label = "Year", sharedData = sd, group = ~year, multiple=F ) dropdown_filter2 <- filter_select( id = "month_filter", label = "Month", sharedData = sd, group = ~month, multiple=F ) map<-leaflet() %>% addTiles() %>% addCircleMarkers(data = sd) # 动态获取默认值 default_year<-min(unique(dat$year), na.rm=T) default_month<-as.character(first(dat$month)) # 使用sprintf简洁拼接带引号的字符串 js <- tags$script(HTML(sprintf(' function filter_default(){ document.getElementById("year_filter").getElementsByClassName("selectized")[0].selectize.setValue("%s",false) document.getElementById("month_filter").getElementsByClassName("selectized")[0].selectize.setValue("%s",false) } $(document).ready(filter_default); ', default_year, default_month))) browsable(tagList(js, bscols(dropdown_filter,dropdown_filter2), map ))
额外说明
- 你也可以用
paste0实现拼接,写法如下:js <- tags$script(HTML(paste0(' function filter_default(){ document.getElementById("year_filter").getElementsByClassName("selectized")[0].selectize.setValue("', default_year, '",false) document.getElementById("month_filter").getElementsByClassName("selectized")[0].selectize.setValue("', default_month, '",false) } $(document).ready(filter_default); '))) - 遇到JS相关的问题时,建议打开浏览器开发者工具(按F12)查看控制台,能快速定位语法错误,这类问题都可以通过这种方式排查。
内容的提问来源于stack exchange,提问作者Anke
相关产品推荐
相关产品推荐

