简体   繁体   English

js.erb文件由于无法从多个控制器传递局部变量而无法呈现局部

[英]js.erb files not rendering partials due to a failure to pass them locals from multiple controllers

I'm having trouble passing locals to a partial shared by three different views, each related to different actions in different controllers. 我无法将本地人传递给由三个不同视图共享的局部视图,每个视图都与不同控制器中的不同操作有关。 The partial and the locals passed to it work without a problem when working with html requests, but I cannot get them to work when issuing xhr requests. 使用html请求时,传递给它的partial和locals可以正常工作,但是发出xhr请求时,我无法使它们工作。 Let me show you my code to explain myself better. 让我向您展示我的代码以更好地说明自己。

So, I have this partial 所以,我有这部分

# app/views/shared/_vote_form.html.erb

  <div id="vote_form">
  <% if post.votes.find_by(user_id: current_user.id).nil? %>
    <%= render partial: "votes/vote", locals: { postv: post, 
                                                vote: post.votes.build } %>
  <% else %>
    <%= render partial: "votes/unvote", locals: { postu: post, 
                                                  vote: post.votes.find_by(user_id: current_user.id) } %>
  <% end %>
</div>

As you can see, this partial renders one of two partials depending on the outcome of an if statement: 如您所见,此部分根据if语句的结果呈现两个部分之一:

# app/views/votes/_vote.html.erb

<%= form_for([postv, vote], remote: true) do |f| %>
  <%= hidden_field_tag 'vote[vote]', 1 %>      
  <%= f.submit "Vote", class: "btn" %>
<% end %>

# app/views/votes/_unvote.html.erb

<%= form_for([postu, vote], html: { method: :delete }, remote: true) do |f| %>
  <%= f.submit "Unvote", class: "btn btn-primary" %>
<% end %>

As I mentioned, this partials are shared by three different views associated to different actions in different controllers. 正如我提到的,该部分由与不同控制器中不同动作相关联的三个不同视图共享。

# app/views/posts/show.html.erb

<div class="post-vote-form">
  <%= render partial: "shared/vote_form", locals: { post: @post } %>
</div>

Which is associated to the following action in the following controller: 与以下控制器中的以下操作相关联:

class PostsController < ApplicationController

  def show
    @post = Post.find(params[:id])
  end
end

Another view 另一种观点

# app/views/users/feed.html.erb

<% @feed_items.each do |f| %>
  <div class="vote-button">
    <%= render partial: "shared/vote_form", locals: { post: f } %>
  </div>
<% end %>

Associated to the following controller#action 与以下控制器关联

class UsersController < ApplicationController

  def feed
    @user = User.find_by(id: current_user.id)
    @feed_items = @user.feed
  end
end

And finally 最后

# app/views/categories/other.html.erb

<% @gal_items.each do |f| %>
  ...
  <%= render partial: "shared/vote_form", locals: { post: f } %>
<% end %>

Associated to controller#action 与controller#action关联

class CategoriesController < ApplicationController
  def other
    @other = Category.find(7)
    @gal_items = @other.posts
  end
end

As you can see, the forms send an xhr request to create/destroy an instance of Vote (I have routes for Vote nested in Post . That's why the form_for takes two arguments). 如您所见,表单发送一个xhr请求来创建/销毁Vote的实例(我在Post嵌套了Vote路由。这就是form_for需要两个参数的原因)。 These requests are handled by the following actions in the VotesController 这些请求由VotesController中的以下操作处理

class VotesController < ApplicationController

  def create
    @post = Post.find_by(id: params[:post_id])
    @vote = @post.votes.build(vote_params)
    @vote.user_id = current_user.id
    @vote.save
    respond_to do |format|
      format.html { redirect_to @post }
      format.js 
    end
  end

  def destroy
    @vote.destroy
    respond_to do |format|
      format.html { redirect_to @post }
      format.js
    end
  end
end

And these two js.erb files come into play: 这两个js.erb文件开始起作用:

# app/views/votes/create.js.erb

$("#vote_form").html("<%= escape_javascript(render :partial => 'votes/unvote', locals: { postu: @post,
                                                                                      vote: @post.votes.find_by(user_id: current_user.id)}) %>");

And

# app/views/votes/destroy.js.erb

$("#vote_form").html("<%= escape_javascript(render :partial => 'votes/vote', locals: { postv: @post.each,
                                                                                   vote: @post.votes.build }) %>");

The way I am presenting these last two js.erb files work for the view # app/views/posts/show.html.erb as the values for the locals are taken directly from the VotesController actions, but I have not been able to find a way to make it work for the other two views (which are @something.each do |f| ) that render these partials, as I cannot pass the appropriate values to the locals for the form_for arguments to work. 我呈现这最后两个js.erb文件的方式适用于视图js.erb # app/views/posts/show.html.erb因为当地人的值直接来自VotesController动作,但我无法找到一种使它对呈现这些部分的其他两个视图( @something.each do |f| )起作用的方法,因为我无法将适当的值传递给本地方法,以使form_for参数起作用。 I have tried with a helper to pass values to the locals depending on the url, but without success. 我已经尝试过使用一个帮助程序,根据URL将值传递给本地人,但没有成功。 It seems obvious that I cannot get these js.erb files to render the partials with appropriate values for the locals because I cannot retrieve the variables from their respective controllers. 似乎很明显,我无法获取这些js.erb文件来为js.erb提供具有适当值的js.erb变量,因为我无法从它们各自的控制器中检索变量。

So, bottomline, is there a way to make it work through these js.erb files, or will I have to sort this out using pure JQuery? 因此,最重要的是,是否有办法使其通过这些js.erb文件工作,还是我必须使用纯JQuery来解决? Has anyone faced something like this? 有没有人遇到过这样的事情? I am sorry that I cannot make a question that requires a more specific answer. 很抱歉,我无法提出需要更具体答案的问题。 Hope you guys can help. 希望你们能提供帮助。

Did you try this? 你有尝试过吗?

class UsersController < ApplicationController

  def feed
    @post = Post.find(params[:id])
    @user = User.find_by(id: current_user.id)
    @feed_items = @user.feed
  end
end

class CategoriesController < ApplicationController
  def other
    @post = Post.find(params[:id])
    @other = Category.find(7)
    @gal_items = @other.posts
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM