Rails 3, как мне обновить страницу с помощью рекурсивного цикла (построение графа дерева)? - PullRequest
0 голосов
/ 31 марта 2012

У меня следующая ситуация.

В модели я заполняю таблицу, которая имеет древовидную структуру. У меня есть модель графика, которая имеет has_many: узлы и модель узла, которая имеет столбец «содержимого», который заполняется в течение следующего:

class Graph < ActiveRecord::Base

   def start_collecting
    self.content_collection(self.nodes.first)
   end

   def content_collection(root)
    root.children.all(:order  => "idx DESC").each do |node|
    #Here the function in Node model is called, that populates 'content' column in node's table.
     content_array << node.content.to_s
     self.children_content = content.array
     self.save!
     child.collect_content
     if !node.children.blank?
      self.content_collection(node)
     end
    end
   end  

Вопрос в том ... Я хочу, чтобы прогресс отображался на веб-странице (app / views / graphs / show.html.erb). Пока я делаю это:

 setInterval(function(){
   var text = <%= array_or_string_for_javascript(@graph.children_content)%> ;
   var pjs = Processing.getInstanceById("graphsketch");
   pjs.update(text);
 }, 3000);

Так что я просто перерисовываю содержимое @ graph.children_content на экране каждые 3 секунды ... Интересно, как лучше всего было бы нарисовать содержимое каждого @ node.content с помощью этого синхронизированного обновления? Очевидно, что если я просто напишу цикл .each в show.html.erb, я буду продолжать получать содержимое последнего @node в цикле ... В основном мне интересно, как перевести цикл из приведенной выше модели в представление и сделать прогресс виден?

Надеюсь, это достаточно ясно, пожалуйста, дайте мне знать, если я объясню лучше ...

РЕДАКТИРОВАТЬ ::

Итак, следуя совету, теперь я имею в graph_controller.rb:

def getstatus
  @graph = Graph.find(params[:id])
  @graph_so_far = @graph.get_graph  
  respond_to do |format|
    format_js
  end
end

в Graph.rb:

def get_graph(root = self.nodes[0], word_ary = [])
  @root = root
  @root.children.all(:order  => "idx DESC").each do |child|
   n_node = (child.depth*2).to_s+child.content
   word_ary << n_node
   child.parent_relation.collect_videos_multiple_cats
    if !child.children.blank?
     self.get_graph(child, word_ary)
    end
   end
  return word_ary
end

На графиках / show.html.erb:

  <script>
 $(document).ready(function () {
  setInterval(function(){
    var idx  = "<%= @graph.id %>";
    $.get("getstatus/", {idx} )
      },1000);
 });      
  </script>
 <%= javascript_include_tag "pjs" %>
<canvas id="graphsketch" data-processing-sources="/assets/pjs/graphBuilder2_2.pde"></canvas>

В графиках / getstatus.js.erb

var text = <% = array_or_string_for_javascript (@sentence_so_far)%>; var pjs = Processing.getInstanceById ("graphsketch"); оповещения (текст); pjs.update (текст);

Оповещение в getstatus.js.erb никогда не срабатывает.

На маршрутах (конечно):

 resource :graphs do
   collection do
     get 'getstatus'
   end
 end 

Что я делаю не так? Еще раз большое спасибо за помощь ..

1 Ответ

1 голос
/ 01 апреля 2012

Позвольте мне убедиться, что я понимаю, вы хотите показать график целиком по мере его роста, обновления каждые 3 секунды, правильно?

Первое, что я хотел бы сделать, это создать действие AJAX в GraphController.это полное содержимое графика до сих пор

def getstatus
  @graph_so_far = Graph.???  
  respond_to do |format|
    format_js
  end
end

Конечно, вам нужно будет добавить новый маршрут

Затем в getstatus.js.erb (в том же каталоге, что и show.html.erb)

var text = <%= array_or_string_for_javascript(@graph_so_far)%> ;
var pjs = Processing.getInstanceById("graphsketch");
pjs.update(text);

Это ваше первое обновление, теперь все, что вам нужно сделать, установить таймер и запустить тот же AJAX-вызов через 3 секунды, я использую jquery.timers.js,но что угодно, через 3 секунды отправьте еще один AJAX-запрос на URL / graph / getstatus (или как вы там назвали свой маршрут), начав цикл заново.

...