【问题标题】:How to add locals to a render call within a js.erb file如何将本地变量添加到 js.erb 文件中的渲染调用
【发布时间】:2018-03-02 03:40:35
【问题描述】:

我的 js.erb 文件从我的 Rails 5.0.4 应用程序远程调用。

<% if @admin_invitation.present? && @admin_invitation.valid? %>
<%my_view = j (render partial: "shared/invitation_card",:user => @admin_invitation.invited_id, :email => @admin_invitation.invited_email, :type => "admin" ) %>
$(".invites.admins .row").prepend("<%=my_view %>");
<% end %>

App.refresh( "<%= j(render 'shared/alerts') %>" );

当我对部分中的值进行硬编码时,它按预期工作,但是当我从这个 js.erb 文件中将它们作为本地值输入时,它们不会通过 (nil)。值得注意的是,我从非远程 haml 视图渲染了部分视图,它工作得很好。

这是我尝试过的渲染方式(我知道有些已经过时,但只是为了进行完整性检查)

render partial: "shared/invitation_card", :locals=> { :email => "admin@gmail.com", :type => "admin" }
render partial: "shared/invitation_card", object: "admin@gmail.com", as: "email"
render partial: "shared/invitation_card", email: "admin@gmail.com", type:"admin"
render partial: "shared/invitation_card", locals: { email: "admin@gmail.com", type: "admin" }

其他人对 从 rails 5 中的 js.erb 渲染 haml 部分有问题

编辑:

这里是调用上面js.erb的控制器方法。

def create
    if params[:invited_status] == "temporary_invitation_user"
      result = CreateGroupInvitation.call(invitation_model: GroupFollowInvitation, group_id: params[:group_id], inviter: current_user, invited_email: params[:invited_email], notification: "created_group_follow_email_invitation")
    else
      result = CreateGroupInvitation.call(invitation_model: GroupFollowInvitation, group_id: params[:group_id], inviter: current_user, invited_id: params[:invited_id] , notification: "created_group_follow_invitation")
    end

    if result.success?
      @invitation = result.invitation
      @invited = params[:invited_id] == "null" ? params[:invited_email] : User.find(params[:invited_id])
      flash.now[:success] = "Your follow invitation was sent"
    else
      if result.error_message.present?
        flash.now[:info] = result.error_message
      else
        flash.now[:error] = "An error happend"
      end
    end

    respond_to do |format|
      format.js { render layout: false }
    end
  end

【问题讨论】:

    标签: javascript ruby-on-rails ruby ajax render


    【解决方案1】:

    您没有指定如何调用js.erb,但我建议的最佳方法如下。

    第 1 步 - 构建视图

    首先在您的视图中包含带有remote: true 选项的链接、表单或按钮

    例如

    <%= form_with(model: @invitation) do |f| %>
    ...
    <% end %>
    

    第 2 步 - 了解路由

    route.rb:invitations 的资源路由生成以下路由:

    new_invitation GET  /invitations/new(.:format) invitations#new                           
                   POST /invitations(.:format)     invitations#create                                      
    

    您在提交时查看invitations/new.html.erb 中的表单将对url /invitations 执行POST 请求。

    AJAX的解释

    在 Web 开发中,您可以在服务器和客户端之间执行 2 种类型的请求, Synchronous or asynchronous requests。在同步请求中,客户端/浏览器将向后端服务器执行 HTTP request,后端服务器将以 response 响应。浏览器将停止并开始加载,直到他收到完整的响应。

    在异步请求中,request and response 循环将不包括浏览器停止加载。

    您的javascript文件只是客户端/浏览器资产管道中包含的一个文件,即下载的所有jscssimagesfonts当用户在http://yourwebsite.xyz 访问您的页面并对该url 执行get 请求时,由浏览器执行。您的服务器会执行包含所有这些信息的响应。

    因此js 文件无法找到来自server 应用程序或database 中的查询的变量。两个东西是分开的,一个是你的服务器,一个是客户端。

    如果您想拥有该变量并将其动态添加到客户端/浏览器asynchronously,那么您需要使用AJAX

    需要从客户端向后端服务器执行get 请求,响应将包含json 格式的@invitation 变量

    第 3 步 - 构建您的控制器

    Rails 路由器在/invitations 接收到POST 请求,并将请求重定向到控制器invitations 操作create。参数通过ActionController::Parameters对象params传递。

    运行 Ruby on Rails 的服务器以 3 种不同的格式响应请求: 用于呈现视图的 HTML JS在前端执行脚本代码。 JS文件invitations/create.js.erb已经被客户端通过资产管道下载了,这只是一个执行它的命令。 JSON 以json 格式发送@invitation 对象,它将在/invitations.json 可用

    # app/controllers/invitations_controller.rb
    # ......
    def create
      @invitation = Invitation.new(params[:invitation])
    
      respond_to do |format|
        if @invitation.save
          format.html { redirect_to @invitation, notice: 'Invitation was successfully created.' }
          format.js
          format.json { render json: @invitation, status: :created, location: @invitation }
        else
          format.html { render action: "new" }
          format.json { render json: @invitation.errors, status: :unprocessable_entity }
        end
      end
    end
    

    第 4 步 - 将结果异步附加到页面

    invitations/create.js.erb 中,您可以包含您的 js 代码,您可以使用 invitations#create 操作中的实例变量

    $("<%= escape_javascript(render @invitation) %>").appendTo("#invitations");
    

    more info about working with AJAX and Rails

    【讨论】:

    • 感谢 Fabizio Bertoglio 提供的所有信息!正如我上面所说,我的路线正常工作,并且当我不使用本地人时,视图呈现完美。如果我只是在部分中硬编码一些测试值并且不通过本地,它看起来很棒!我阅读了您的 cmets 并试图找到我错过的东西,但我认为我很好!从调用所有这些的视图来看,我正在使用 javascript ajax 发布请求!
    【解决方案2】:

    我找到了答案。其实很简单

    render partial 'view' locals: {k1: v1, k2:v2} 不会给你一个本地哈希。它只是定义了局部变量 k1 和 k2 以在您的局部变量中使用。您不需要从“本地”哈希中提取它们。

    render 'view' locals: {k1: v1, k2:v2} 确实为您提供了一个包含 k1, v2 的本地哈希。在您提取它们之前,它们不会被定义。这种不一致让我失望了。我的代码已准备好让它们位于本地哈希中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多