2

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を選択していますが、それでもまったくすっきりしないと思います。これを行うより良い方法はありますか?パフォーマンスと DRY の問題のために、同じビューで 2 回ループさせたくないので、OPTION A の選択を拒否しました。間違っている場合は修正してください。

ありがとう。

4

3 に答える 3

2

それが私のプロジェクトであれば、おそらくこの問題を JavaScript 側に移すでしょう。緯度と経度を item タグのどこかにある data- 属性に入れ、目立たないスクリプトを使用してそれらを読み取ります。(例が必要な場合はお知らせください。)

それが不可能な場合、私は個人的にオプション A を好みます。まず第一に読みやすさ (特に content_for に慣れていない場合は理解しやすい) と第二に、リファクタリングが容易であるため、データの収集をメソッドに移動できます。モデルまたはヘルパーに。ここでは DRY は実際には適用されません。同じデータセットをループしている場合でも、非常に異なることを行っているからです。

とはいえ、パフォーマンスへの影響についてはよくわからなかったので、少しテストを実行しました。私は自分のアプリの 1 つで 500 のクライアント レコードを取得し、オプション A を使用してリンクのリストをレンダリングし、続いてそれらのデータを content_for ブロックにマッピングし、Ruby の組み込み Benchmark モジュールを使用してベンチマークを行いました (erb ではなく haml ですが、私は確信しています読みにくいわけではありません。)

- 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)

次に、2 つのループ (1つ 1eachmap)で同じことを行いました。

- 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-ビューなどの属性に移動します。

<% @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 を別のファイルにきちんと保持し、データの収集をクライアント側で行うことができます。

于 2012-08-25T17:24:09.963 に答える