Cloud2016 我知道在 ui.R 里面换行是 br() 函数,它执行结果是 <br/> 我想写一个这样的函数 add_br <- function(n){ paste(rep_len( x = "<br/>", length.out = n), sep = "", collapse = ",") } add_br(3) 替换 br(),br(),br() 但是实际上不行
Cloud2016 思维上还是差一点, Shiny 渲染出来其实是个网页,是个网页,是个网页!所以字符串需要转化一下,用 shiny 里的 HTML() 函数包裹一下就可以了 HTML(rep(as.character(br()), 3)) <br/> <br/> <br/>
yihui Cloud2016 你这是降维再升维,不用这样绕道,直接用原生数据结构就好了,这样不会毁损 HTML 标签的数据结构: rep_el = function(n, el = htmltools::br()) { htmltools::tagList(rep(list(el), n)) } 如无必要,尽量避免使用 HTML() 函数,就像在 JS 里如无必要,尽量不要操纵 element.innerHTML 属性一样。 又及:当你需要用到两个或以上的换行时,你可能更应该考虑用 CSS 而不是用换行符控制垂直间距。
Cloud2016 yihui CSS 又是一个大坑,还不会用,最近在看 <https://mastering-shiny.org/action-modules.html> 想写点小函数替换掉 Shiny 里面重复度比较高的代码
nan.xiao 如果用 CSS,还是根据 CSS 框架原生的网格系统实现更好。那么问题来了:学挖掘机技术 shiny 啥时候才能升级到支持 spacing 的 Bootstrap 4 呢 😅 虽然我已经不得不把 Bootstrap 4 的一些东西 backport 到 3 很久了 …… 所以 br(), br(), br() 虽然违背了 DRY 原则,它的存在也是一种无奈的选择(做成函数复用稍好一些),在GitHub上搜索,可以看到市面上真是充斥了这种写法,连我也私下偷偷用。
yihui nan.xiao 好问题。我上个月才开始看 Bootstrap 4,我以为两周就可以搞定从 3 到 4 的升级,而不知道 Shiny 团队已经在这个问题上默默死磕好几个月了。Joe 比较保守,想为 3 续命若干年,而我比较激进,想着既然连 Bootstrap 官方团队都已经不再支持 3 了我们何必再为它续命,而且这种外观框架的升级换代一般不会导致致命的问题,所以长痛不如短痛。我花了两周时间已经把 R Markdown 里的多数问题都解决了,不过在 Joe 的死谏下,我还是投降了,听从他们先为 3 续命,来一个尽量平稳的过渡。 现在回想起来,R Markdown 当初采用 Bootstrap 框架可能是个错误的决策。对 Markdown 这种简单语言来说,Bootstrap 里的 99.9% 的代码可能都是没有用处的,因为它的大多数元素都没法通过 Markdown 生成。当然,我又跑题了(只是作为背锅侠来倒倒苦水)。
nan.xiao @yihui Bootstrap 3 到 4 给我的感觉基本上是大幅重写了,向后兼容相当困难。如果是个人项目,我连兼容都不会考虑,而是会直接新建一个 shiny2 😂 可能现在大家也都意识到了,在前端深度绑定 Boostrap 给 shiny 带来了巨大的便利和流行度,同时也带来了这些灵活度问题。对升级我还是很期待的,虽然这意味着可能需要给旧应用打一些补丁。 在升级策略这事上,感觉都有一定道理,到最后都不是一个技术问题了,而是因为人和人的理念存在差异(开箱即用 + 向后兼容 vs. 高度可定制 + 最新科技),只能说理解万岁吧。作为商业公司,有时也不得不需要考虑用户和开发者的感受。 R Markdown 的 Bootstrap 依赖我到目前暂时还可以接受,毕竟绑定不像 shiny 那样深度,如果自己想,可以完全重置和定制,就像英国政府开发的那全套 govdown 🤔至于更本质的解耦,就期待 R Markdown v3 之类的能实现吧 ……