1

私は標準のレールアプリ形式を持っています。

私はこれらのコントローラを持っています:

class StaticPagesController < ApplicationController

  def help
  end

  def about
  end

end

そして私はファイルを持っていますapp/assets/javascripts/static_page.js.coffee

私は2つのことをしたい:

  1. static_pages のページの 1 つを実行しているときにのみ、この JavaScript をロードします。

  2. コントローラー内の特定のアクションに応じて、さまざまな js 呼び出しを行うことができます。

JavaScript ファイルは次のようになります。

//general javascript code
if (isThisHelpPage) {
   //Run some help page code
}

if (isThisAboutPage) {
   //Run some about page code
}

最初の問題は、次のapp/assets/javascripts/application.jsようなルールを追加することで、ファイルで何らかの方法で解決する必要があると思います。

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

//= (isItStaticController? render static_page.js.coffee)

しかし、どうすればそれができるのか知りたいですか?

4

4 に答える 4

1

残念ながら、アプリのデプロイ時にプリコンパイルされるため、アプリケーションの js ファイルに条件を追加することはできません。ここであなたのために働くことができる2つの潜在的なアプローチがあります:

1) 上記のようにすべての JavaScript を 1 つのファイルに配置し、次のようにコードでページを設定します。

<script> page = "Help" </script> or <script> page = "About" </script>

スクリプトは次のようになります。

if(page === "Help") .... else if(page === "About") ....

2) もう 1 つのオプションは、ページごとに個別の js ファイルを作成し、yield :head ブロックを介してレイアウトに組み込むことです。ヘルプ ファイルでは、次のようになります。

<% content_for :head %>
  <%= javascript_include_tag 'help' %>
<% end %>

私は個人的に、自分のアプリでは 2 番目のアプローチを好みます。

于 2012-08-28T22:03:30.483 に答える
0

私はこれをどのように処理するかを説明します。私には、リクエストごとにApplicationController実行されるメソッドがあります。before_filter

def prepare_common_variables
  controller_name = self.class.name.gsub(/Controller$/, '')
  if !controller_name.index('::').nil?
    namespace, controller_name = controller_name.split('::')
  end

  @default_body_classes = ["#{controller_name.underscore}_#{action_name} ".downcase.strip]
  @default_body_classes = ["#{namespace.underscore}_#{@default_body_classes.join}".strip] if !namespace.nil?
end

app/views/layouts/application.html.erb私は次のものを持っています

<body class="<%= yield :body_classes %> <%= @default_body_classes.join(' ') %>">

の場合StaticPagesControllerhelpアクションが実行されると、次の<body>タグが生成されます。

<body class="static_pages_help">

次に、私は私の中にこのような方法を持っていますapp/assets/javascripts/application.js.erb

Array.prototype.diff = function(a) {
  return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};

var DEEFOUR = (function (deefour) {
  deefour.Utility = (function (utility) {
    utility.hasBodyClass = function() {
      var args = Array.prototype.slice.call(arguments);
      if (args.length === 0 || $('body').get(0).attr('class') == "") return false;

      return args.diff($('body').get(0).attr('class').split(/\s/)).length == 0;
    };

    return utility;
  }(deefour.Utility || {}));

  return deefour;
}(DEEFOUR || {}));

最後に、あなたの私の同等物では、app/assets/javascripts/static_page.js.coffee私はこのようなものを持っています

$(function(){
  if (!DEEFOUR.Utility.hasBodyClass('static_pages_help')) return;

  // code for your help page
});

$(function(){
  if (!DEEFOUR.Utility.hasBodyClass('static_pages_about')) return;

  // code for your about page
});

あなたの見解では、これは素晴らしいことです

<% content_for :body_classes, :some_custom_class %>

または特定のアクション内で

@default_body_classes << "some_other_custom_class"

Javascript で照合する特定のクラスを条件付きで追加できます。

// *both* 'static_pages_help' and 'some_other_class' are required
if (!DEEFOUR.Utility.hasBodyClass('static_pages_help') || !DEEFOUR.Utility.hasBodyClass('some_other_class')) return;

hasBodyClass(...)任意の数の引数を受け入れます。それらをリストするだけです。これは、フォームの送信に失敗したときに同じ Javascript を実行したいアクションなどnewに役立ちます。create

if (!DEEFOUR.Utility.hasBodyClass('some_controller_new', 'some_controller_create')) return;

のようprepare_common_variablesな単一の名前空間のみを許可するため、少し調整する必要があることに注意してください。SomeNamespace::TheControllerSomeNamespace::AnotherNamespace::TheController

于 2012-08-28T22:04:27.460 に答える
0

ここでのベスト プラクティスは、content_for ヘルパー メソッドを使用することです。@Adamで説明されているようなものですが<%= yield :script_files %>、レイアウトファイルの最後に a を入れてから呼び出すことをお勧めします

<% content_for :script_files do %>
  <%= javascript_include_tag 'your_js_file' %>
<% end %>

あなたがしたい行動の中から。Ryan Bates が初期の Railscast で述べたのと同様のアプローチに従うことで、これをさらにクリーンに行うことができます。

module ApplicationHelper
  def javascripts(paths)
    content_for :script_files do
      javascript_include_tag(paths.is_a?(Array) ? paths.join(',') : paths)
    end
  end
end

次に、アクション ビューから呼び出し<% javascripts 'your_js_file' %>て、そのファイルを含めることができます。

于 2012-08-28T22:22:54.347 に答える
0

static_pages のページの 1 つを実行しているときにのみ、この JavaScript をロードします。

まず、アセット パイプラインは静的なアセット ファイルをコンパイルして作成しますoffline。つまり、ユーザー リクエストの処理中 (本番環境) にコントローラー名に基づいてバンドルを動的に作成することはできません。

ただし、 (StaticPages コントローラー<%= javascript_include_tag "static_page_manifest.js" %>の) 対応するレイアウト ファイルで ( を含む) の代わりに別のステートメントを使用application.jsして、特定のビューの特定の JavaScript を定義することができます。たとえば、次のようにすることができますapp/assets/javascripts/static_page_manifest.js

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

//= static_page

または、動的な JavaScript モジュールを含める場合は、requirejs( requirejs-rails) などを使用できます。

コントローラー内の特定のアクションに応じて、異なる js 呼び出しを行うことができます

idこれは、コントローラーとアクションの名前に応じた値でbody タグをチェックすることで実現できます! 例えば:

<body id="static_pages_<%= controller.action_name %>">
...

そして、JavaScript バンドルでこの id 値をチェックして、特定のコード スニペットを実行できます。

于 2012-08-28T22:24:19.823 に答える