如何从JS ERB内部执行辅助方法?

mar*_*ion 13 javascript ajax jquery ruby-on-rails ruby-on-rails-4

我有一个帮助方法dashboard_helper.rb,看起来像这样:

  def show_number_of_comments(node)
    if node.comments_count == 1
      "#{node.comments_count} Comment"
    else
      "#{node.comments_count} Comments"
    end
  end
Run Code Online (Sandbox Code Playgroud)

在我的常规dashboard#index视图中,我称之为:

<h4 class="card-comments-title"><%= show_number_of_comments(node) %></h4>
Run Code Online (Sandbox Code Playgroud)

但是我想在添加新注释时通过AJAX更新渲染的元素,所以在我看来comment#create.js.erb,我想引用那个帮助方法,但是当我尝试这个时,它不起作用:

$('#<%= @card_id %> .card-comments-title').html('<%= show_number_of_comments(@node) %>');
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,它的工作原理是:

$('#<%= @card_id %> .card-comments-title').html('<%= @comment_count %> Comments');
Run Code Online (Sandbox Code Playgroud)

后者的问题是它不处理多元化.

什么是最好的方法来解决这个问题?

编辑1

当我说它不起作用时,这就是我的意思:

NoMethodError at /nodes/5/comments
==================================

> undefined method `show_number_of_comments' for #<#<Class:0x007fbd3715e5b8>:0x007fbd3715d4d8>

app/views/comments/create.js.erb, line 5
----------------------------------------
Run Code Online (Sandbox Code Playgroud)

此外,该@node对象在我Comments#Create这样声明:

  def create
    @node = Node.find(params[:node_id])
    @comment = current_user.comments.new(comment_params)
    @comment.node = @node
    @card_id = params[:card_id]
    @comment_count = @node.comments_count + 1
    current_user.events.create(action: "commented", eventable: @comment)

    binding.pry

    respond_to do |format|
      if @comment.save and @node.save
        format.js
      else
        format.js
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

当我通过binding.pry上面的方式停止执行时,我尝试做@node,我得到了我期望的值:

[1] pry(#<CommentsController>)> @node
=> #<Node id: 5, name: "Reverse Crunches", family_tree_id: 1, user_id: 1, media_id: 5, media_type: "Video", created_at: "2015-07-25 05:49:51", updated_at: "2015-07-25 21:05:34", circa: nil, is_comment: nil, cached_votes_total: 0, cached_votes_score: 0, cached_votes_up: 0, cached_votes_down: 0, cached_weighted_score: 0, cached_weighted_total: 0, cached_weighted_average: 0.0, cached_user_tag_list: nil, cached_num_user_tags: 0, cached_tagged_user_names: [], comments_count: 3>
Run Code Online (Sandbox Code Playgroud)

编辑2

有时它会失败.它不会向控制台或我的服务器日志输出任何错误,它只是用.card-comments-title空值替换它.

mar*_*ion 5

所以我想出了我想要在我的具体情况下做什么,即在我的JS ERB中复数注释计数,但我还没有弄清楚如何helper_method在我的JS ERB中使用a - 所以这个答案并没有真正回答这个问题.

但是,我在这里记录这个,以防其他人有类似的问题,我的解决方案可以帮助他们.

在我的JS ERB中,我所做的就是使用Rails方法复数.我完全忘了它,直到我输入这个问题,它就像一个魅力.

这是我的代码片段create.js.erb:

$('#<%= @card_id %> .card-comments-title').html('<%= pluralize(@comment_count, "Comment") %>');
Run Code Online (Sandbox Code Playgroud)

像魅力一样工作,但这仍然没有回答我在这里引用/使用帮助方法的问题.

  • 我不确定这是否得到了回答.只是想回答,因为现在我好奇,因为我的助手在js.erb为我工作.我认为你的@node一定不能在你的create.js.erb文件中使用,这就是为什么它不适合你.即使你调用复数,复数仍然是一个被调用的辅助方法.如果您的'@node'不存在,则node.comments_count必须崩溃. (2认同)

Ana*_*oly 5

如果不需要本地化,您还可以尝试避免使用后端:

var comentsNumber = function(num){
  return (num == 0 || num > 1) ? num + " Comments" : num + " Comment"
};
var domObject = $('#<%= @card_id %> .card-comments-title');
Run Code Online (Sandbox Code Playgroud)

基本上,您可以通过AJAX调用轻松更新对象并触发内容重新加载:

var htmlContent = comentsNumber(<%= @comment_count %>);
domObject.html(htmlContent);
Run Code Online (Sandbox Code Playgroud)