0

Railsアプリケーションに取り組んでおり、event_calendargemの「来月」リンクをajax応答に変換しようとしています。

リンクをリモートに設定しました:

  def month_link(month_date)
    link_to I18n.localize(month_date, :format => "%B"),
      {:month => month_date.month, :year => month_date.year},
      remote: true
  end

jsに応答するように言った...

respond_to do |format|
  format.html
  format.js { render text: "help me!" }
end

そしてそれは動作します!

Started GET "/calendar/2012/6" for 127.0.0.1 at 2012-07-03 15:27:42 -0500
Processing by CalendarController#index as JS
  Parameters: {"year"=>"2012", "month"=>"6"}
  Event Load (0.3ms)  SELECT "events".* FROM "events" WHERE (('2012-05-27 05:00:00.000000' <= end_at) AND (start_at< '2012-07-01 05:00:00.000000')) ORDER BY start_at ASC
  Rendered text template (0.0ms)
Completed 200 OK in 14ms (Views: 0.7ms | ActiveRecord: 0.3ms)

まあ...それが実際に何もレンダリングしない部分を除いて、私はそれを渡します。レンダリングなしで指示しただけformat.jsでは、実際にはjsファイルに応答しません。

レンダリングが表示されない原因は何ですか?

更新

  • このようにURLにアクセスするとlocalhost:3000/calendar/2012/6.js、期待どおりに機能することに気づきました。リンクの設定に問題があると思いますか?

  • わかりました。jsファイルを機能させましたが、理由がわかりません。私は誤用したと思いますrender(一度デバッグ目的で使用したことを誓ったかもしれませんが)。レンダリングは、htmlリクエストに応答するときに実際にhtmlページをレンダリングするだけだと思います。ajaxリクエストのためにjsonをjavascriptに渡すので意味があります。

  • 問題のもう1つの部分は、またはのいずれindex.js.coffee.erbかでCoffeeScriptを使用しようとしていたことindex.js.erb.coffeeです。一番長く機能していると思っていたのですが、実際に起こっていたのindex.js.erbは、すでに削除していたのに、最初に書いたオリジナルを使っていたということです。サーバーを再起動すると、すべてが壊れました。

4

2 に答える 2

1

これを試して:

def month_link(month_date)
  link_to I18n.localize(month_date, :format => "%B"),
  {:remote=>true, :month => month_date.month, :year => month_date.year}
end

使用する link_to の形式は次のとおりです。

link_to(body, url_options = {}, html_options = {})

:remote=>true は url_options に入れたいです。:month & :year キーが何のためにあるのかわかりませんが、それらが html オプションである場合は、次のようにする必要があります。

def month_link(month_date)
  link_to I18n.localize(month_date, :format => "%B"),
  {:remote=>true}, 
  {:month => month_date.month, :year => month_date.year}
end
于 2012-07-03T21:26:58.693 に答える
1

デフォルトでは、remoteオプションはレンダリングまたはリダイレクトの試みを無視しているようです。Ajax のポイントは、これらの両方を防止することであることを考えると、その理由はわかります。

自己参照のために、リモートを作成すると(私の知る限り)何が起こるかを次に示しますlink_to

jquery_ujs.js の 51 行目

  $.rails = rails = {
    // Link elements bound by jquery-ujs
    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]',

linkClickSelectorの 300 行目にこの関数があります。

  $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) {
    var link = $(this), method = link.data('method'), data = link.data('params');
    if (!rails.allowAction(link)) return rails.stopEverything(e);

    if (link.is(rails.linkDisableSelector)) rails.disableElement(link);

    if (link.data('remote') !== undefined) {
      if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; }

      if (rails.handleRemote(link) === false) { rails.enableElement(link); }
      return false;

    } else if (link.data('method')) {
      rails.handleMethod(link);
      return false;
    }
  });

handleRemoteが AJAX を処理すると仮定すると、このモンスターを見つけるために 107 行目にたどり着きます。

// Submits "remote" forms and links with ajax
handleRemote: function(element) {
  var method, url, data, crossDomain, dataType, options;

  if (rails.fire(element, 'ajax:before')) {
    crossDomain = element.data('cross-domain') || null;
    dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);

    if (element.is('form')) {
      method = element.attr('method');
      url = element.attr('action');
      data = element.serializeArray();
      // memoized value from clicked submit button
      var button = element.data('ujs:submit-button');
      if (button) {
        data.push(button);
        element.data('ujs:submit-button', null);
      }
    } else if (element.is(rails.inputChangeSelector)) {
      method = element.data('method');
      url = element.data('url');
      data = element.serialize();
      if (element.data('params')) data = data + "&" + element.data('params');
    } else {
      method = element.data('method');
      url = rails.href(element);
      data = element.data('params') || null;
    }

    options = {
      type: method || 'GET', data: data, dataType: dataType, crossDomain: crossDomain,
      // stopping the "ajax:beforeSend" event will cancel the ajax request
      beforeSend: function(xhr, settings) {
        if (settings.dataType === undefined) {
          xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
        }
        return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
      },
      success: function(data, status, xhr) {
        element.trigger('ajax:success', [data, status, xhr]);
      },
      complete: function(xhr, status) {
        element.trigger('ajax:complete', [xhr, status]);
      },
      error: function(xhr, status, error) {
        element.trigger('ajax:error', [xhr, status, error]);
      }
    };
    // Only pass url to `ajax` options if not blank
    if (url) { options.url = url; }

    return rails.ajax(options);
  } else {
    return false;
  }
},
于 2012-07-04T17:06:18.110 に答える