看 http://ruby-china.org/topics/15604 这篇看到其中提到 nav 的 active class 的写法,才想起自己对这点一直有些疑惑。
自己一般是这么写:
li class=(controller_name == 'articles' ? 'active' : nil)
靠 controller_name 或是 action_name 来判别当前页面的 controller 或 action,在对应的 li 上添加 active。
要是更复杂的情况,比如有 namespace,可能还要用到 controller_path。
貌似没什么问题,但一直不太清楚这么写好不好,还有没有更好的写法?
跑去翻 ruby-china 的代码,看到是用了 render_list,可没找到这个方法的定义,这是某个 gem 提供的么?
不复杂的话,我会移到前端去做.. 参照一下这个:https://github.com/jhough10/Centurion/blob/master/js/centurion.js#L18
第一种,就要重新渲染整个页面,才看到变化;页面不容易出错,简单。
第二种,有多个方法: 1、页面不刷新,只更新主体内容,nav 使用 js 操作状态; 这方法需要自己掌控好页面结构,比如 pjax。
2、页面整个刷新,但把 nav 的状态从页面(如.erb)传给 js,然后由 js 根据状态值进行操作; 其实,我觉得和第一种方法一样,甚至还不如第一种;
3、如果 nav 的多个内容,是同时加载,那么就用 js 控制,没必要重新刷新页面。
暂时想到就这些了。建议使用第一种,前期没必要把页面搞复杂;爱折腾的另算!
LS 的好复杂..
我的方法是用 JS 拿到 nav 下面所有的链接,移除 active
,然后跟当前浏览器地址匹配,对得上的就给它加上 active
。当然,这有很大的局限。不过省了很多 if else。另外,可以扩展到级联菜单上
#11 楼 @hooopo 我觉得基于 URL 来高亮的思路过于理想化,复杂一点的业务系统里面经常出现两个完全不同的 URL 要高亮同一个链接
我觉得换个思路想会简单很多,页面上某个链接是否要高亮,属于页面展示逻辑,那么就应当将这块逻辑写到对应的 view 里面,比如 nav 上这么写
<li class="<%= 'active' if curr_nav == "A" %>">aaa</li>
<li class="<%= 'active' if curr_nav == "B" %>">bbb</li>
而在页面针对相应的变量赋值就行
<% curr_nav = 'A' %>
当然这些代码用 helper 封装一下用起来会更简单
#8 楼 @saiga 曾经也是这样做,但 JS 一般要等页面 render ready 才做,用户会感觉延迟。server 端做会好一些。
我在 view 里是
render_nav 'name1'
render_nav 'name2'
render_nav 'name3'
render 整个 nav list。
然后在 controller 里配置当前要 active 的 nav。
controller 里
current_nav 'name1'
对所有 action 生效。
action 里
current_nav 'name2'
只应用当前 action。
render_nav
和current_nav
分别为 helper 和 concern,需要自己实现。