0

我有一个控制器,它将为小部件提供服务:

class WidgetsController < ApplicationController
  def widget1
    respond_to do |format|
      format.html
      format.js { render js: js_constructor }
    end
  end

  def widget2
    respond_to do |format|
      format.html
      format.js { render js: js_constructor }
    end
  end

  private
  def js_constructor
    content = render_to_string(params[:action], layout: false)
    "document.write(#{content.to_json})"
  end
end

这个控制器会变得更大,所以我想避免在所有操作中重复这段代码:

respond_to do |format|
  format.html
  format.js { render js: js_constructor }
end

任何想法?

编辑:只是为了给出一些背景......

路线是灵活/动态的:get 'widgets/:action', to: 'widgets#:action'

因此,如果我访问widgets/widget1它将呈现视图widget1.html.erb

如果我将脚本包含在另一台服务器中,它将在那里构建 widget1:

<script type='text/javascript' src='http://localhost:3000/widgets/widget1.js'></script>
4

2 回答 2

1

答案是元编程:

class WidgetsController < ApplicationController
  [:widget1, :widget2].each do |name|
    define_method(name) do
      respond_to do |format|
        format.html
        format.js { render js: js_constructor }
      end
    end
  end

  private

  def js_constructor
    content = render_to_string(params[:action], layout: false)
    "document.write(#{content.to_json})"
  end
end
于 2015-06-09T19:10:13.370 回答
1

我会编写一个将“视图”作为参数的操作。你基本上是在做一个#show呈现不同视图的动作。

get 'widgets/:template', to: 'widgets#show'

class WidgetsController < ApplicationController
  def show
    respond_to do |format|
      format.html { render params.require(:template) }
      format.js { render js: js_constructor }
    end
  end

  private
  def js_constructor
    content = render_to_string(params.require(:template), layout: false)
    "document.write(#{content.to_json})"
  end
end
于 2015-06-09T19:22:49.163 回答