【问题标题】:json erb template cannot find other html partialjson erb模板找不到其他html部分
【发布时间】:2011-03-23 06:42:24
【问题描述】:

我正在尝试一个 json 响应,其中某些值是由部分呈现的 html

#projects_Controller.rb

def index
  respond_to do |f|
    f.json 
  end
end

# index.json.erb

  {
     "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer') %>"
  }

但我收到以下错误:

  ActionView::Template::Error (Missing partial projects/disclaimer with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>
  [:json], :locale=>[:en, :en]} in view paths "c:/rails/app/views", "c:/rails/vendor/plugins/more/app/views", "C:/Ruby192/lib/ruby/gems/1.9.1/gems/devise-1.1.8/app/views")

似乎 JSON 请求在其名称中呈现部分带有 .json.erb 但不是 .html.erb,这就是我所拥有的。 有没有办法让我指定'html'。

添加: 如果请求是“js”,并且在 index.js.erb 我呈现几乎相同的代码: # index.js.erb

  disclaimer = {
     "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer') %>"
  }

它确实找到了 projects/disclaimer.html.erb 并正确呈现它。我想知道为什么会有这样的不一致,如果一个人请求js,其模板中的任何部分渲染都会寻找partial_name.html.erb,但如果一个人请求json,部分渲染会请求partial_name.json.erb?

谢谢

【问题讨论】:

    标签: ruby-on-rails json partial-views


    【解决方案1】:

    知道了:只需要 .json.erb 文件中的这一行

    所以完整的 index.json.erb

          <% self.formats = ["html"] %>
          disclaimer = {
            "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer',
                        :content_type => 'text/html'), 
                        :locals => {:localVariable => @localVariable} 
                    %>"
          }
    

    【讨论】:

    • 这种方法也适用于渲染 JSON 的控制器内部;我设置了self.formats = [:html],然后render_to_string(:partial=&gt;'an_html_partial', :locals=&gt;{:whatever=&gt;whatever}),然后就可以很好的渲染json了。
    • 如果您还有其他 json 部分,您可能想要改为 self.formats += [:html]。
    【解决方案2】:

    我的回答与 Nik 上面的类似。我有以下 json.erb 模板的助手:

    # helpers useful for json.erb templates
    module JsonHelper
    
      # Same as render but force actionview to look for html templates instead of json.
      def render_html(options={}, locals={}, &block)
        old_formats = formats
        self.formats = [:html] # hack so partials resolve with html not json format
        render options, locals, &block  
    
      ensure
        self.formats = old_formats 
      end 
    
      # json escape a string. For example <%=json "some { string }" %>
      def json(value)
        raw value.to_json
      end 
    end
    

    所以现在我可以编写像

    这样的模板了
    {
      "html": <%=json render_html(:partial => 'some_partial') %>,
      "status": success
    }
    

    如果 actionview 允许像 23tux 的示例中那样使用 content_type 进行渲染(这对我不起作用),那就更好了。如果只对 *.html.erb 进行 html 转义而不是对所有 *.erb 文件进行转义也会更好。

    【讨论】:

      【解决方案3】:

      对于未来的读者,您可以像这样传递格式参数。

      = render partial: 'user', locals: {xyz: @xyz}, :formats => [:html]
      

      【讨论】:

        【解决方案4】:

        我不确定我是否正确,但也许你可以使用这样的内容类型:

        disclaimer = {
          "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer', :content_type => 'text/html'), :locals => {:localVariable => @localVariable} %>"
        }
        

        :locals 只是你想将一个 var 传递给部分。

        【讨论】:

        • 不不,我认为你是对的:rails 被要求提供 json,所以它提供的任何东西,包括任何渲染都必须是 json 而不是 html.erb。因此,当我在响应中请求 partial.html.erb 时,它会抛出一个错误,指出找不到 partial.JSON.erb。奇怪的是,如果我在标题中要求 .js(JSONP?),这意味着 rails 应该在 .js.erb 结尾提供所有部分,但是这一次,它不介意提供 .html.erb 并且不会说没有找到。这与我的观点不一致......但是在添加 :content_type => 'text/html' 之后,它仍然会抛出同样的错误
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多