6

オートコンプリートやライブ検索などの基本的な Ajax リクエストに Javascript を使用するアプリケーションがあります。たとえば、次の方法でライブ検索を実装しました。潜在的な問題を見つけたので、それについてあなたと話したいので、より良いコードを作りたいと思います.

app/controllers/company_controller.rb

def livesearch
  @companies = Company.search(params[:query])
  render :partial => "companies", :locals => {:companies => @companies}
end

app/views/companies/_companies.html.haml

- if companies.empty?
  None
- else
  %table#company_list
    %tr
      %th Name
      %th Description
      %th Products
      %th
    = render companies

アプリ/ビュー/会社/_livesearch_box.html.haml

= content_for :scripts, "jlivesearch companies"
= form_tag "#", :autocomplete => :off, :remote => true do
  %span.light
    Search:  
  = text_field_tag :search
  :javascript
    $('#search').livesearch({
      searchCallback: update_listed_companies,
      queryDelay: 200,
      innerText: "Search companies"
    });

public/javascripts/company.js

function update_listed_companies(query) {
  if(typeof query == "undefined")
    query = "";

  $("#company_list_container").showWith(
    "/companies/livesearch?query=" + query,
    false
  );
}

public/javascripts/application.js

(function($) {
  $.fn.showWith = function (what, popup) {
    element = this;
    $.get(what, function(data) {
      element.html(data);
      if(popup)
        element.bPopup();
    });
    return element;
  };
})(jQuery);

私のコードの最適性について疑わしい点は次のとおりです。

  • に Javascript コードがあり_livesearch_box.html.hamlます。
  • に入れても、その部分public/javascripts/companies_livesearch.jsをハードコーディングする必要があります。#search
  • 私は(レンダリングされる#company_list_containerdivです)にハードコーディングしています。_companies.html.hamlpublic/javascripts/companies.js
  • /companies/liveseach?query=にハードコードされたパスがありますpublic/javascript/companies.js
  • 私はCoffeeScriptを使用していません。主な理由は、(少なくともBaristaを使用している場合)純粋なjavascriptコードをどこか(たとえば. app/coffeescripts/)で見つけてpublic/javascripts. しかし、私のアプリケーションでは、私の中にいくつかの.js.erbファイルもありますapp/views/companies。たとえば、私は app/views/companies/_vote.js.erb$("#vote_link_<%= escape_javascript(@company.id.to_s) %>").html("<%= escape_javascript(vote_link_for(@company)) %>") で次を使用する投票システムを持っています: Ajax リクエストであり、コントローラーのvoteおよびunvoteアクションによってレンダリングされます。Hamlファイル内でCoffeeScriptをコンパイルするcoffee-haml-filterがあることは知っていますが、それは私が正確に必要としているものではなく、通常は推奨されておらず、汚いもの(?)と見なされています。

したがって、質問は少なくとも次のとおりです。

  • 私の中にCoffeeScriptを入れる方法はapp/views/*/*.js.*
  • app/views/*/*.js.*ファイルを持っている必要がありますか?
  • 最も効率的かつエレガントな方法で、JavaScript にハードコーディングされたすべての要素 ID とパスを削除するにはどうすればよいですか?

長い質問で申し訳ありませんが、最後までお付き合いいただきありがとうございます。

4

1 に答える 1

6

ルート

JS/CSに書き込むことができるjs-routes (私のフォーク)のようなソリューションがいくつかあります。Router.post_path(3)このようにして、URL のハードコーディングを回避できます。

JS と ERB の混合

JS と Ruby を混在させないことをお勧めします。ほとんどの場合、JS コードをリファクタリングすることで回避できます。結果は読みやすくなり、単純に純粋な JS/CS ファイルに移動できます。

# based on your vote-link example and assuming that your link
# looks like:
#
# %a(href="#"){:"data-company-id" => @company.id} Vote
# => <a href="#" data-company-id="6">Vote</a>

makeAllCompaniesVotable: () ->
  $('.company a.voteLink').click ->
    companyId = $(this).data('company-id')
    $.ajax
      url: Router.vote_company_path(companyId)
      # ...

邪悪な eval-magic を行わない限り、 も必要ありませんescape_javascript。ただし、パーシャル内から JavaScript を削除する必要があります。jquery.livequery移行を容易にしました。

$(`.company`).livequery ->
  # do something with $(this)

.companyドキュメントに a が挿入されるたびに呼び出されます。

DOM パスのハードコーディング

特定の dom-tree (または特定のビュー) のコードを書いている場合、私はそれを悪い習慣とは考えません。邪魔にならない JS を書くことは、CSS を書くことに似て#company_list_containerいます。

$("#vote_link_<%= escape_javascript(@company.id.to_s) %>") # this is ugly though

フロントエンドから JS コードを呼び出す

静的なCoffeeScriptファイルとビューの間のインターフェースを持つために、私は次のようなものを書く傾向があります:

:javascript
  $(function(){Companies.index()});
  $(function(){Application.globalEnhancements()});

私の見解の最後に。これにより、CoffeeScript で作成した関数が呼び出され、必要なすべてのスクリプトでサイトが拡張されます。より良いアプローチがあるかもしれません (JavaScript 用の Rails のようなルーターを使用するなど - Backbone.js を参照) が、それはシンプルで、私にとってはうまくいきます。

また、かなり頻繁にデータが必要な場合 (例: current_user):

:javascript
  window.current_user = #{current_user.to_json};

ただし、効率的なリファクタリング方法はないと思います。ERB/JS の混乱を取り除くために、多くのリファクタリングを行う必要がありました。それでも価値があります。

于 2011-03-14T15:13:35.103 に答える