如何将局部变量添加到js.erb文件中的渲染调用中

时间:2017-09-20 22:51:00

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

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

<% 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 partials时遇到问题?

修改

以下是调用上面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

2 个答案:

答案 0 :(得分: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中的表单会向网址 POST发送/invitations个请求。

AJAX的解释

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

在异步请求中,request and response周期不包括停止加载的浏览器。

您的javascript文件只是客户端/浏览器资产管道中包含的一个文件,它们都是jscss,{{1}当用户访问images页面并向fonts发出http://yourwebsite.xyz请求时浏览器下载的{}和get。您的服务器执行包含所有这些信息的响应。

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

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

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

第3步 - 构建控制器

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

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

获取
/invitations.json

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

# 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 中,您可以包含您的js代码,您可以使用invitations/create.js.erb操作中的实例变量

invitations#create

more info about working with AJAX and Rails

答案 1 :(得分:1)

我找到了答案。实际上很简单

渲染部分“视图”本地:{k1:v1,k2:v2}不会为您提供本地哈希。它只是定义了局部变量k1和k2,用于你的局部变量。您无需从“本地”散列中提取它们。

渲染'view'本地符号:{k1:v1,k2:v2}确实为你提供了一个k1,v2的局部哈希值。在您提取它们之前,它们不会被定义。这种不一致让我失望了。我的代码已准备好让他们在本地哈希中。