8

jQueryがHTMLファイルでレンダリングしようとしているRailsアプリケーションがあります。これのポイントは、jQuery はページに固有であるため、ヘッダーに配置してすべてのページにロードしたくないということです。これが私がファイルに対して行ったことです

messages_controller.rb

 # GET /messages/new
 def new
    @message = Message.new
    @users = User.where('id != ' + current_user.id.to_s)
    #if @message.save
       #MessageMailer.new_message(@message).deliver

    respond_to do |format|
       format.html # new.html.erb
       format.js
    end
    #end
 end

/messages/new.html.erb

<div class="row">
    <div class="large-12 columns">
        <div class="panel">
            <h1>New message</h1>
            <%= render 'form' %>

            <%= link_to 'Back', messages_path, :class => "button small" %>
        </div>
    </div>
</div>

/messages/new.js.erb

$("h1").html('hello'); //for testing that it works

別のファイルに追加する必要があるものはありますか? HTML と .js の両方をロードするために必要なリクエストはありますか?

4

4 に答える 4

8

なぜこれがうまくいかないのですか?

あなたの方法が、あなたが望むことを達成するための特に標準的な方法だとは思いません。JS テンプレートがロードされない理由は、ブラウザーが HTML を要求する場合は HTML テンプレートで、ブラウザーが JS を要求する場合は JS テンプレートで応答するようにコントローラーが設定されているためです。ブラウザはどちらか一方しか要求できないため、両方が返されることはありません。

つまり、コントローラーの Respond_to ブロックは、送信されるすべての種類のコンテンツをすべての要求でリストするのではなく、さまざまな種類のコンテンツの要求に応答する方法をコントローラーに指示しています。

解決策 1: すべてのページに JS をロードする

ここで考慮すべき点がいくつかあります。まず、特定のページで JS が使用されていないからといって、それ自体をロードしない正当な理由にはなりません。Rails は、Sprockets を介して、すべての JS を連結して 1 つのファイルに縮小します。このファイルが変更されない限り、ユーザーのブラウザによってキャッシュされます。これにより、新しい JS を取得するために追加のリクエストを行う必要がないため、ユーザーがこの JS を必要とするページにアクセスしたときの応答が速くなります。

JS が実行されるべきではないコンテンツで実行されていることに懸念がある場合は、JS を実行したいページに一意の識別子を追加し、その識別子をJS。例えば:

$("h1.special").html('hello');

解決策 2: content_for を使用する

ただし、JS を個別にロードすることが有益な場合もあります。私の意見では、それを達成するための最良の方法は、個々のビューで必要な場合に、コンテンツを頭に追加するブロックのコンテンツを用意することです。

したがって、アプリケーションのレイアウトでは次のようになります。

#layouts/application.html.erb
<head>
  #Other head content here

  <% if content_for?(:head) %>
    <%= yield(:head) %>
  <% end %>

  #Other head content here
</head>

#messages/new.html.erb
<% content_for :head do $>
  <%= javascript_include_tag "messages_new.js" %>
<% end %>
#Other view stuff here

#assets/messages_new.js
$("h1").html('hello');

その場合、message_new.js は content_for ブロックをインクルードするビューでのみインクルードされるため、実行されます。他のページには表示されません。

解決策 3: HTML に JavaScript を含めるだけ

または、JS が最後に読み込まれるかどうかを気にしない場合は、new.html.erb の下部にインクルード ヘルパーを追加するだけです。

#messages/new.html.erb
#Other view stuff here
<%= javascript_include_tag "messages_new.js" %>
于 2013-10-24T15:44:23.580 に答える
5

遅くなって申し訳ありませんが、次を使用して「/messages/new.js.erb」で JavaScript を呼び出すことができます。

メッセージ/new.html.erb

link_to "Link", "", remote: true

そのリンクをクリックするたびに、「/messages/new.js.erb」が起動します。

于 2016-06-14T19:21:57.957 に答える
5

私が理解していることから、/messages/new を要求するときに new.html と new.js を提供する必要があります。

RailsコントローラーはjsまたはHTMLを使用し、両方を使用することはありません。HTTP はそのようには機能しません。HTTP 要求に応答して送信されるファイルは 1 つだけで、同時に 2 つを送信することはできません。

アクションの Respond_to ブロックの目的は、html リクエスト (クラシック ブラウジング) には html を使用し、リクエストが js の場合は js を使用することであり、それが ajax に使用するものです。

必要な場合は、erb に js 参照を追加する必要があります。他に方法はありません。

于 2013-10-24T15:45:49.707 に答える