Rails:部分应该知道实例variables吗?
例如,瑞安·贝茨的nifty_scaffolding这样做
edit.html.erb
<%= render :partial => 'form' %>
new.html.erb
<%= render :partial => 'form' %>
_form.html.erb
<%= form_for @some_object_defined_in_action %>
那个隐藏的状态让我感到不舒服,所以我通常喜欢这样做
edit.html.erb
<%= render :partial => 'form', :locals => { :object => @my_object } %>
_form.html.erb
<%= form_for object %>
那么哪个更好一些: a)有部分访问实例variables或者b)传递它所需要的所有variables的一部分?
我一直在selectb),但是我碰到了一个小菜。
some_action.html.erb
<% @dad.sons.each do |a_son| %> <%= render :partial => 'partial', :locals => { :son => a_son } %> <% end %>
_partial.html.erb
The son's name is <%= son.name %> The dad's name is <%= son.dad.name %>
son.dad进行数据库调用来取父亲! 所以我要么必须访问@dad,这将回到a)具有部分访问实例variables,或者我将不得不在本地通过@dad,改变渲染:部分为<%= render:partial =>'partial' ,:locals => {:dad => @dad,:son => a_son}%>,由于某种原因,将一堆增值税传递给我的部分会让我感觉不舒服。 也许别人也这样认为。
希望这是有道理的。 寻找一些有关这整个事情的见解…谢谢!
在Rails的最新版本中,渲染局部variables和传递局部variables比较容易。 而不是这个。
<%= render :partial => 'form', :locals => { :item => @item } %>
你可以这样做。
<%= render 'form', :item => @item %>
我不在Nifty Scaffold生成器中执行此操作以保持向后兼容性,但是我将在以后的版本中对此进行更改。
至于是否可以使用partials中的实例variables。 我觉得是这样的。 在所有的实际中,缺点是什么? 如果你不一致,事情肯定会失控,但我喜欢应用这些指导方针。
-
永远不要创build一个实例variables只是为了在部分之间分享它。 通常这意味着您将只能共享控制器资源对象。
-
如果部分名称与资源名称相同,则将其作为本地名称传递给
<%= render @item %>
。 -
如果部分将在多个控制器之间共享,那么只能使用当地人。
无论如何,这对我来说都很好。
奖金提示:如果您发现自己将许多本地人传入了部分内容,并希望其中的一部分是可选的,请创build一个呈现部分内容的辅助方法。 然后总是通过帮助器方法,所以你可以做一个干净的界面与可选参数渲染部分。
在partials中使用@instance_variables是不好的devise。
在部分工作中使用实例variables,但如果需要更改,可能会使维护应用程序变得更加困难。
在部分中使用实例variables的不利之处在于,您在部分范围(耦合)之外的部分中创build了一个依赖关系。 这使得部分难以重用,并且当您想要在一个部分中进行更改时,可以在应用程序的多个部分中强制进行更改。
使用实例variables的部分:
- 必须在使用局部variables的任何控制器中的实例variables更改实例variables名称或其types或数据结构时更改
- 当使用实例variables的方式发生变化的同时,使所有使用该偏移的控制器动作以相同的方式改变
- 不鼓励重复使用,因为它们只能被轻易地用于设置具有相同名称和数据的实例variables的操作中
相反,将本地人传递给部分:
<%= render 'reusable_partial', :item => @item %>
现在,由于仅部分引用item
而不是@item
,呈现呈现reusable_partial的视图的操作可以自由更改,而不会影响reusable_partial和其他呈现它的操作/视图:
<%= render 'reusable_partial', :item => @other_object.item %>
而且,这可以在没有@item的情况下重用:
<%= render 'reusable_partial', :item => @duck %>
如果将来我的@duck
改变,并且不再像reusable_partial所期望的那样(对象的接口发生变化),我也可以使用一个适配器来传入reusable_partial期望的那种types的项目:
<%= render 'reusable_partial', :item => itemlike_duck(@duck) %>
总是?
有很多情况下,你可能不需要这样的分离部分,在短期内使用实例variables更容易。 但是,很难预测您的应用程序的未来需求。
因此,这在成本相对较低的情况下成为普遍的实践。
你可以有两种方式。 在你的部分顶部:
<% item ||= @item %>
这样,它可以或不经过本地variables,提供了一个健全的默认,但不抑制交替使用部分。
我投了一个非常具体的原因 – 干! 如果你开始传递一个variables – 就像那样 – 接下来的事情你知道 – 这是一个混乱 – 让我们假设你需要改变你的variables的名称或其他方式 – 然后你需要去所有的意见,并改变他们而不是一个部分。 另外 – 如果你改变你的偏好 – 假设它产生了一个带有一些结果的表格,它会改变你的所有视图,所以你需要知道哪些视图被使用,一个合适的IDE应该能够帮助你,但是我也喜欢在视图的顶部有一个小的注释部分 – 我只是提到它的用途和原因 – 帮助另一个程序员,它可以帮助您记住,以防您需要回到部分和修改。 但是局部的全部意义在于,不需要从视图中传递任何东西,所以如果variables以某种方式变化,就不必修改调用partial的所有地方。
最终这是一个deviseselect – 说实话,除非你正在运行一个Facebook的额外的查找你做的不是什么大不了的事情,但它不是很干。
PS:试想一下,你实际上可以抽象出你在辅助方法中调用partial的方式,那么如果你调用partial的方式需要改变 – 那么你只需要修改一个地方。