【问题标题】:In Rails 3, how does one render HTML within a JSON response?在 Rails 3 中,如何在 JSON 响应中呈现 HTML?
【发布时间】:2011-01-28 10:08:42
【问题描述】:

我正在将一个应用程序从 Merb 1.1 / 1.8.7 移植到 Rails 3 (beta) / 1.9.1,它使用包含 HTML 片段的 JSON 响应,例如,在用户记录上指定更新的 JSON 容器,以及更新的用户行看起来像。在 Merb 中,由于控制器方法返回的任何内容都会提供给客户端,因此可以将一个 Hash 放在一起,将渲染的部分分配给其中一个键并返回 hash.to_json(尽管这肯定不是最好的方法。)在 Rails 中, 似乎要将数据返回给客户端必须使用render,并且render只能调用一次,因此由于部分渲染,将散列渲染为json将不起作用。

通过阅读,似乎可以将该数据放入 JSON .erb 视图文件中,并在其中包含 并进行渲染。除此以外,是否有解决此问题的 Rails 方式(返回包含一个或多个 HTML 片段的 JSON)?

在 Merb 中:
控制器:

only_provides :json
...
self.status = 204 # or appropriate if not async
return {
    'action' => 'update',
      'type' => 'user',
        'id' => @user.id,
      'html' => partial('user_row', format: :html, user: @user)
}.to_json

在 Rails 中:
控制器:

respond_to do |format|
  format.json do
    render template: '/json/message-1', 
      locals: { 
        action: 'update',
        type: 'user',
        id: @user.id,
        partial: 'user_row.html.erb', 
        locals: { user: @user }
      }
  end
end

查看:json/message-1.json.erb

{
  "action": <%= raw action.to_json %>,
  "type": <%= raw type.to_json %>,
  "id": <%= raw id.to_json %>,
  "html": <%= raw render(partial: partial, locals: locals).to_json %>
}

【问题讨论】:

标签: ruby-on-rails json merb


【解决方案1】:

还有一个问题有更多关于 json.erb 文件的解决方案。见json erb template cannot find other html partial

【讨论】:

    【解决方案2】:

    我可以在 Rails 中找到的最接近 Merb 原始方法的方法是使用 #render_to_string

    render json: {
      'action' => 'update',
        'type' => 'user',
          'id' => @user.id,
        'html' => render_to_string(partial: 'user_row.html.erb', locals: { user: @user })
    }
    

    这解决了在混合中添加一层 json.erb 模板所带来的相当多的复杂性,无论是我不能说的 Rails Purist 方法;可能通常会使用带有 RJS 的东西。

    【讨论】:

    • 谢谢,我正在寻找这个“render_to_string”方法!
    • 我注意到你也可以只添加 .html 作为扩展名,.erb 会自动添加,如果你使用 slim (.slim) 会很有用
    • 我认为解析格式,在这种情况下,在json/message-1.json.erb 中使用self.formats += [:html] 将是更多 Railsy 处理此问题的方式。在其他非常相似的情况下建议使用此方法:stackoverflow.com/questions/5401696/…stackoverflow.com/questions/7806533/…
    【解决方案3】:
    class UsersController < ApplicationController  
      respond_to :json
    
      def show  
        @user = User.find(params[:id])
        respond_with(@user) do |format|
          if @user.save
            format.json { render :json => @user }
          else
            format.json { render :json => @user.errors, :status => :unprocessable_entity }
          end
        end
      end
    end
    

    【讨论】:

    • 我可能错过了这一点:在这个例子中我可以看到将 HTML 片段放入 JSON 的唯一方法是在 User 上实现 #to_json 并让它渲染部分,这可能会运行与双重渲染问题相冲突,即使不是,也不允许在不同的上下文中使用不同的片段,例如 user_row v. user_detail。这里有什么我没有得到的吗?
    猜你喜欢
    • 2011-05-19
    • 2012-10-09
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多