我不确定这样做的最佳方法是什么,或者我的想法是否存在根本缺陷。
我有一个控制器,可以在#index
动作上创建一个普通的旧Ruby对象(PORO)演示者:
# 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
}
实现这一目标的最佳方法是什么?
答案 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/
希望这有帮助