开发者

How do I start and stop javascript-initiated queries in my Rails app?

I have an app that needs to periodically update a "news" area of the screen as long as my Publisher object has news. When there is no news, that area of the screen is hidden (or simply not rendered), and updating stops. I've used Ryan Bates's excellent Polling for Changes Ra开发者_如何学JAVAilsCast as a starting point, but I'm stuck on a couple of points.

My intention is that if the Publisher object has news, its show() method renders a page with a <div id='news'></div> on it. Javascript will notice that div and replace it (and its contents) with any news that the Publisher has, and retrigger 5 seconds later. When the Publisher has no more news, Javascript will replace the <div id='news'></div> with an empty string. At the next trigger, there will be no more <div id='news'></div>, so the retrigger process will stop. At least, that's the intention.

First, the problems:

  1. Though I know my partial is getting called, it doesn't generate a visible change on the screen
  2. (Perhaps related to 1.) The javascript fn keeps getting called even there is no more news to display.

Briefly, here are the salient parts:

file: public/javascripts/application.js

$(function () {  
  if ($('#news').length > 0) {  
    setTimeout(updateNews, 5000);
  }
});  

function updateNews() {  
    $.getScript('/publisher/update_news.js');  
    setTimeout(updateNews, 5000);
}

file: config/routes.rb

resource :publisher, :only => [:show] do
  member {
    get :update_news
  }
end

file: app/controllers/publishers_controller.rb

def show
end

def update_news
  @publisher = find_publisher
  unless (@publisher.has_news?)
    return head :ok
  end
  # otherwise should render views/publisher/update_news.js.html
end

file: app/views/publisher/show.html.erb

<%= render :partial => 'publishers/show_news', 
           :locals => {:publisher => @publisher} %>

file: app/views/publisher/update_news.js.erb

<% t = escape_javascript(raw(render(:partial => 'publishers/show_news', 
                                    :locals => {:publisher => @publisher}))) %>
$('#news').replace_with(' + <%= t %> + ');

file: app/views/publisher/_show_news.html.erb

<div id='news'>
  <h4>latest news</h4>
  <%= simple_format publisher.news %>
</div>

Rails.logger.debug messages tell me that the _show_news.html.erb partial is getting called, both via the show() method and via the javascript-initiated updateNews() method. But I don't see the changes on the screen and (perhaps related) the updateNews function continues to get called after Publisher.has_news? returns false. (The latter problem would be explained if the jQuery replace_with() function always starts with the originally rendered page, not the results of its own modifications.)

So the two question: 1. Why don't I see visible changes to the screen? Am I mis-using jQUery's replace-with? 2. I'm suspicious of my technique for stopping the updates. What's the right way?


To help with the debugging:

Use fiddler (windows) or a Mac tool to see exactly what is being passed between your html/jScript page on your browser and the server.

Have you tried using the browser debugger to understand what is happening?

My guess is that the js being sent from your .js.erb page is not working well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜