Rails从PORO presenter操作调用JavaScript并将结果返回给View

时间:2015-09-16 10:44:15

标签: javascript ruby-on-rails presenter

我不确定这样做的最佳方法是什么,或者我的想法是否存在根本缺陷。

我有一个控制器,可以在#index动作上创建一个普通的旧Ruby对象(PO​​RO)演示者:

# 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
}

实现这一目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

我使用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/

希望这有帮助