1

問題の説明:

リンクのセットを含むビューがあります。

<% @feeds.each do |f| %>                
  <div class="feed">
    <span class="feed_counts"> <%= f.display_counts %> </span>
    <%= link_to "refresh", { :controller => 'Feeds', :action => "refresh_feed", :feed_id => f.id}, :remote => true, :class => 'refresh_feed_link' %>
    </div>
<% end %>

ユーザーはリンクをクリックして、次のコントローラーメソッドを起動します。

def refresh_feed
  @feed = Feed.find(params[:feed_id])
  @feed.parse
end

次に、対応するspan-elementの内容を@feed.total_count値に変更します。

私の試み:

さて、私が知っているように、ページ全体をリロードせずにそれを行うには2つの方法があります:

方法1:

レイアウトにjsを含めることができます:

<%= render :partial => 'shared/partial_js' %>

そして、partial_jsでこのコードを使用します。

<script type="text/javascript">
  $().ready(function() {

    $('.refresh_feed_link').bind('click', function() {
      $(this).closest('.feed').find('span.feed_counts').text('woo');
    });
 });
</script>

この場合、「$(this)」があり、対応する「span」要素を見つけることができます。しかし、@feed変数値を取得する可能性はありません。

方法2:

追加できます

respond_to do | format |  
  format.js {render :layout => false}  
end

コントローラに追加して、refresh_feed.js.erbファイルを作成します。このJSファイルでは、変数を<%@ feed.total_count%>として使用できますが、複数のリンクのどれがクリックされたかわかりません。つまり、このファイルの$(this)変数は(window)になり、対応するspan要素が見つかりません。

質問:

私が欲しいものを手に入れる方法はありますか?
前もって感謝します。

4

1 に答える 1

1

これを行う方法はたくさんあります。説明した方法を使用して、「どのリンクがクリックされたか」の問題の簡単な解決策を次に示します:dom_id

1)パーシャルを作成します:app / views / feeds / _feed.html.erb

<%= div_for feed do %>
  <span class="feed_counts"> <%= feed.display_counts %> </span>
  <%= link_to "refresh", { :controller => 'Feeds', :action => "refresh_feed", :feed_id => feed.id}, :remote => true, :class => 'refresh_feed_link' %>
<% end %>

2)あなたの見解では:

<%= render @feeds %>

3)refresh_feed.js.erbファイル:

$('<%= dom_id(@feed) %>').replaceWith('<%= escape_javascript( render @feed ) %>');

個人的には別の方法が好きですが、書くのに少し時間がかかるので、別の方法で書く間はここに残しておきます。


第二の方法

入力が簡単なCoffeeScriptとHAMLを使用して、これを行う方法を説明します。これをプレーンなJSとERBに変換するだけで、同じように機能します。

次のようにルートを設定します。

resources :feeds do
  get "refresh_feed", :on => :member

あなたが「フィード」パーシャルを持っていると仮定すると、app/views/feeds/_feed.html.haml

= div_for feed, :class => 'feed_widget' do
  %span.feed_counts= f.display_counts
  = link_to "Refresh", refresh_feed_path(f), :class => 'refresh_link'

任意のビューで:

= render @feeds

// or, more explicit:

= render :partial => 'feed/feeds', :collection => @feeds, :as => :feed

app/assets/javascripts/feeds.js.coffee

# Global Scope for CoffeesScript, ignore for JS
root = exports ? this

# Check page if there are feed widgets on it and initialize a handler for each one.
jQuery ->
  if $('div.feed_widget').length
    $('div.feed_widget').each ->
      new FeedWidget $(this)

root.FeedWidget = (container) ->
  @container = container
  @refresh_link = @container.find('a.refresh_link')
  @feed_counts = @container.find('span.feed_counts')
  this.initialize()

root.FeedWidget.prototype =
  initialize: ->
    self = this
    @feed_counts.click (event) ->
      event.preventDefault()
      $.ajax
        type: 'GET'
        url: self.refresh_link.attr 'href'
        dataType: 'json'
        error: (xhr, status, error) ->
          console.log error
          console.log xhr
        success: (data, status, xhr) ->
          self.feed_counts.text data.feed_counts

次に、コントローラーで:

def refresh_feed
  @feed = Feed.find(params[:id]) #assuming you have a resourceful route to this.
  @feed.parse
  respond_to do |format|
    format.js { render :json => { feed_counts: @feed.counts }, :status => :ok } # use whatever method gets you the feed count here.
  end
end

これで、フィード数だけのJSON応答が得られ、自動的に表示(および機能)してその部分をレンダリングする単一のJSリスナー/ハンドラーウィジェットがあります。かっこいい?

上記のコードは、アプリがないためテストされていないため、必要に応じて調整する必要があります。しかし、質問をしてください、そして、私は答えるために最善を尽くします。

幸運を!

于 2012-11-16T19:51:52.513 に答える