论坛首页 编程语言技术论坛

页面重构,将重构进行到底!

浏览 8449 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-11-22  
view中的bad smells:
1 N多的if else,甚至case语句
  这是本文的重点,在最后着重讲(用block替代if else)。
2 直接调用model的find方法
  对策:将find move到controller中,在view中使用controller传来的对象变量

3 对集合进行复杂的操作
  对策:在将这些操作move到helper中,页面调用规整好的数据
  <% items.sort_by{|item|[item.created_on,item.price]}.each do |item| %>
    #so bad
  <% end %>

===>
  <% sorted_item.each do |item| %>
    #so good
  <% end %>

4 临时变量
  将临时变量的代码段 move到helper中
<% rate_box_id = "rate_box_#{item.id}" %>
<% spinner_id = "spinner_#{item.id}" %>
<%= link_to_remote("rate it!",
:url => item_path(item),
:loading => "$('#{spinner_id}').show()",
:complete => "$('#{spinner_id}').hide();$('#{rate_box_id}').highLight();",
) %>
 <%= image_tag('loading.gif', :id => spinner_id)%

==>
<% with_rate_for item do|spinner,spinner_id| %>
  <% link_to_rate(item,:toggle=>spinner_id) %>
  <% spinner %>
<% end %>

=========用block替代if else==============
1 如果集合为空,显示友好的信息
很多时候,如果取到的结果集合为空,需要显示用户另外的信息。当然一般我们会这么写:
  if(@cart.empty)
    您的购物车是空的
  else
    rend :parial=>'cart'
  end

注意,这是在rhtml中写的。这个逻辑还是比较清晰的,但如果一个页面中有几处这种代码,你就得好好考虑一下重构了.
我们可以把集合为空的内容,提到block中,比如:
<%cart_content do%>
  购物车是空的!+N长的rhtml代码
<%end%>
将if else都转移到helper中:
module CartHelper
    def cart_content(&block) 
    return yield if cart_empty? 
    content=(render :partial => "shared/cart" ,:locals  => {:cart => prepare_cart})  
    concat(content,block.binding)
  end
end

2 面对不同的登陆用户,显示不同的内容
 <%header :guest do %> 
     #略
 <%end%>
 <%header :logged_user do %>
   #略
 <%end%>
 <%header :admin  do %> 
   #略
 <%end%>

helper中的方法
	def header(who) 
		yield if logged_in? who
	end

==========================总结================================
    以上代码,都是一些例子,可能不太具有说服力。但在这里要强调的是,view层难测试,自解释差,难重用。在复杂度综合不便的情况下,我更倾向于helper复杂一些,view简单一些。更何况,一些公共的重复代码搬移以后,的确会达到DRY的目的,这是rails设计中是中贯彻的理念。
  
   发表时间:2008-01-10  
这样一来,可能就是help里面太乱了,什么都往里面塞。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics