Rails вызывает JavaScript из действия ведущего PORO и возвращает результат в View

Я не уверен, как лучше всего это сделать, или мое мышление в корне ошибочно.

У меня есть контроллер, который создает презентатор Plain Old Ruby Object (PORO) в своем действии #index:

# app/controllers/my_controller.rb
class MyController < ApplicationController
    def index
        @my_presenter = MyPresenter.new(
            filter_1: params[:filter_1],
            filter_2: params[:filter_2])
    end
end

И презентатор, который использует данные из нескольких моделей:

# app/presenters/my_presenter.rb
class MyPresenter
    def initialize(filter_1: nil, filter_2: nil)
        @my_data = MyModel.my_scope(filter_1) # scoping in the my_model.rb file
        @my_other_data = MyOtherModel.my_scope(filter_1, filter_2)
    end

    def show(view)
        # Somehow call the my_function.js from here and return the result to the view
    end
end

И, наконец, представление, которое зависит от ведущего:

<!-- app/views/my_controller/index.html.erb -->
<h1>The view</h1>

<%= @my_presenter.show(this) %>

Я хочу, чтобы действие #show ведущего вызывало некоторый JavaScript (код D3 для визуализации) и возвращало результат в представление:

// app/assests/javascripts.js
function my_function(data) {
    // D3 visualisation to go here...
    return null
}

Каков наилучший способ добиться этого?


person Bradley Marques    schedule 16.09.2015    source источник


Ответы (1)


Я успешно использовал ActiveModel::Conversion. Это смешивает несколько вещей, которые позволяют вам связать представление с докладчиком.

В вашем ведущем

class MyPresenter

  include ActiveModel::Conversion

  def initialize(...)
  ...

end

тогда в поле зрения вы можете сделать что-то вроде

<%=h render @my_presenter %>

При этом Rails будет искать представление, представляющее ваш виджет/презентатор в app/views/my_presenters/_my_presenter.html.erb, которое вы можете конкретизировать с помощью своего html.

Чтобы получить подключение D3, вам, вероятно, следует прикрепить его после загрузки документа. Предполагая, что у вас есть jQuery, вы можете сделать что-то вроде

$(function() {
  var my_function = function(data) { 
    // d3 stuff here
  };
  my_function(data)
});

Вероятно, это может находиться в вашем application.js или, может быть, в части докладчика, заключенной в тег <script>.

Здесь есть описание этой техники: http://blog.carbonfive.com/2014/01/07/presenters-to-widgets-with-activemodelconversion/

Надеюсь это поможет

person mr rogers    schedule 16.11.2015