问题描述:
我有一组链接的视图:
<% @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值。
我的尝试:
嗯,我知道有两种方法可以不重新加载整个页面:
方式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文件中,我可以将我的变量用作&lt;%@ feed.total_count%&gt;,但我不知道我的多个链接中的哪一个被点击了。换句话说,这个文件中的$(this)变量将是(窗口),我找不到相应的span-element。
问题:
有没有办法得到我想要的东西?
提前谢谢。
答案 0 :(得分: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侦听器/处理程序窗口小部件,它将自动显示(和函数)并将您呈现为部分。好吧?
请注意,由于我没有您的应用,因此上述代码未经过测试,因此您必须根据自己的需要对其进行优化。但提出问题,我会尽力回答。
祝你好运!