我有一个模型类别has_many:subcategories
我正在使用代码来填充子类别的值,根据使用Ajax的视图中的类别下拉值下拉。这是代码:
_form.html.erb
<%= f.select :category_id, @categories, {}, :tab_index => 4, :onchange => "#{remote_function(:url => {:action => "populate_subcategories"},
:with => "'category_id='+value")}" %>
<div id = "subcategories_div">
<%= render :partial => "subcategories", :object => @subcategories %>
</div>
deals_controller.rb
def new
@deal = Deal.new
@categories = Category.all.map { |category| [category.name, category.id]}
@subcategories = @categories.first.subcategories.map { |subcategory| [subcategory.name, subcategory.id] }
end
def populate_subcategories
subcategories = Subcategory.where(:category_id => params[:category_id]).map { |subcategory| [subcategory.name, subcategory.id] }
render :update do |page|
page.replace_html 'subcategories_div', :partial => 'subcatgories', :object => subcategories
end
end
最后_subcategories.html.erb
<%= f.select :subcategory_id, subcategories, {}, :tab_index => 5 %>
我的问题是,在代码page.replace_html 'subcategories_div', :partial => 'subcatgories', :object => subcategories
中,为什么我们将子类别定义为局部变量并将其作为对象传递给部分?我们本来可以这样写的
def populate_subcategories
@subcategories = Subcategory.where(:category_id => params[:category_id]).map { |subcategory| [subcategory.name, subcategory.id] }
render :update do |page|
page.replace_html 'subcategories_div', :partial => 'subcategories'
end
end
使用@subcategories作为实例变量,以便它在部分中可用,就像在Rails中的普通视图一样。
同样在_subcategories.html.erb
中<%= f.select :subcategory_id, @subcategories, {}, :tab_index => 5 %>
和_form.html.erb
<div id = "subcategories_div">
<%= render :partial => "subcategories" %>
</div>
为什么第一种方法比第二种方法更受欢迎?是因为我们只有一个变量传递给部分?第一种方法是否有任何性能改进?
答案 0 :(得分:2)
原因是您希望您的部分视图与视图无关。通过使用@subcategories,您可以在部分视图和视图之间创建不必要的依赖关系。这意味着要再次使用相同的部分,您必须确保定义了@subcategories,并且可能不是这种情况。例如,您可能只定义了@my_subcategories或@filtered_subcategories。更糟糕的是,你可能有@subcategories和@filtered_subcategories,你可能想要使用相同的局部显示两者。在这种情况下,最好能够将子类别传递给partial,而不是依赖于设置的实例变量。这样你的部分就是模块化的,并且符合面向对象的封装原则。
例如:
<h1><%= My Subcategories %></h1>
render :partial => 'subcatgories', :object => @my_subcategories
<h1><%= Other Subcategories %></h1>
render :partial => 'subcatgories', :object => @other_subcategories
答案 1 :(得分:1)
你可以优雅地将你的ivars命名为部分,
render 'subcatgories', :subcategories => @hashtags
或
render 'subcatgories', :subcategories => @legals
然后你可以在你的部分中使用subcategories
,使用ivar就像它的名字假装是
去看看ActionView::Rendering#render
有更长的params形式来实现相同的行为...(:partial => 'subcatgories', :locals => {:subcategories => @hashtags}
)
我相信:subcategories => @hashtags
比:object => @hashtags