gpt4 book ai didi

ruby-on-rails - 一个 View 中有多个类似的循环,更好的做法?

转载 作者:行者123 更新时间:2023-12-04 05:34:36 25 4
gpt4 key购买 nike

使用 Rails 3。我的观点有 2 个选项:

选项 A:

<% @items.each do |item| %>
...
<% end %>
...

<script>
var items = [
<% @items.each do |item| %>
['<%= item.name %>', <%= item.lat %>, <%= item.lng %>],
<% end %>
];
</script>

选项 B:
<% @items.each do |item| %>
...
<% content_for :items_array do %>
['<%= item.name %>', <%= item.lat %>, <%= item.lng %>],
<% end %>
<% end %>
...

<script>
var items = [<%= yield :items_array %>];
</script>

目前我选择了 选项 B ,但我仍然认为它一点也不整洁。有没有更好的方法来做到这一点?我拒绝选择 选项 A 因为由于性能和 DRY 问题,我不希望它在同一个 View 中循环两次,如果我错了,请纠正我。

谢谢。

最佳答案

如果这是我的项目,我可能会将这个问题转移到 javascript 端。将 lat 和 long 放入项目标签中某处的数据属性中,并使用不显眼的脚本来读取它们。 (如果你想要一个例子,请告诉我。)

如果这不可能,我个人更喜欢选项 A,首先是为了可读性(它更容易理解,特别是如果您不熟悉 content_for),其次因为它更容易重构,我们可以将收集数据移动到一个方法中在模型上或者可能成为助手。 DRY 在这里并不真正适用,因为即使您循环通过相同的数据集,您也在用它做非常不同的事情。

也就是说,我不太确定性能影响,所以我进行了一些测试。我在我的一个应用程序中获取了 500 条客户记录,并使用选项 A 呈现链接列表,然后将它们的数据映射到 content_for block 并使用 Ruby 的内置 Benchmark 模块对其进行基准测试(它在 haml 而不是 erb 但我确定读起来并不难。)

- bench = Benchmark.measure do
%ul#client-list
- @clients.each do |client|
%li
= link_to client.company, client
- content_for :foobar do
= "['#{j client.name}', '#{j client.company}', '#{j client.email}'],"

= javascript_tag do
var nearbys = [#{yield :foobar}];

%p= bench.to_s

结果,大约 370 毫秒
 0.370000 0.000000 0.370000 ( 0.397476)

然后我对两个循环做了同样的事情(一个 each 一个 map ):
- bench = Benchmark.measure do
%ul#client-list
- @clients.each do |client|
%li
= link_to client.company, client

= javascript_tag do
= "var nearbys = [#{ @clients.map { |client| "['#{j client.name}', '#{j client.company}', '#{j client.email}']," }}]"

%p= bench.to_s

结果,大约 80 毫秒:
0.080000 0.000000 0.080000 ( 0.077940)

您可能想自己检查结果,但似乎 content_for 方法不是解决此问题的非常有效的方法。

编辑:仅供引用,这是使用 ree 1.8.7 和 rails 3.2.6 测试的

编辑2:

如何在不使用内联 javascript 的情况下重写它的示例。我首先将所有必需的参数移动到 data-属性,例如在 View 中:
<% @items.each do |item| %>
<div class="item" data-name="<%= item.name %>"
data-lat="<%= item.lat %>"
data-long="<%= item.long %>">
<%= item.name %>
</div>
<% end %>

(您也可以从 div 中获取名称,但将所有内容放在 data-attributes 中更加一致。)

然后在你的javascript中,你可以按如下方式映射数据(假设jquery):
var nearbys = $('.item').map(function() {
return [ $(this).data("name"), $(this).data("lat"), $(this).data("long") ];
});

这样,您可以将所有 javascript 整齐地保存在一个单独的文件中,并在客户端完成数据收集。

关于ruby-on-rails - 一个 View 中有多个类似的循环,更好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12123400/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com