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

时间:2015-07-15 08:16:50

标签: javascript jquery ruby-on-rails ajax 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

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

<h4 class="card-comments-title"><%= show_number_of_comments(node) %></h4>

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

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

但是当我这样做时,它起作用:

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

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

最好的方法是什么?

修改1

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

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

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

app/views/comments/create.js.erb, line 5
----------------------------------------

此外,@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

如上所述,当我通过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>

修改2

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

6 个答案:

答案 0 :(得分:5)

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

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

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

以下是我create.js.erb的代码段:

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

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

答案 1 :(得分:5)

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

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

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

var htmlContent = comentsNumber(<%= @comment_count %>);
domObject.html(htmlContent);

答案 2 :(得分:3)

显示单数/复数文本的更好的解决方案是通过i18n。您可以尝试以下内容:

# config/locales/en.yml

en:
  comments:
    zero: No comments
    one: 1 comment
    other: %{count} comments

然后在您看来,您将其用作:

$('#<%= @card_id %> .card-comments-title').html("<%= t('comments', count: @node.comments_count) %>");

关于帮助程序无法正常工作的问题:鉴于dashboard_helper.rb目录中有app/helpers/,您的帮助程序应该可以正常工作。有了这个问题,您已经描述了以下行的工作原理:

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

以下没有:

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

如果show_number_of_comments(@node)的输出可能使用console.log,您可能会找到更好的答案。可能需要使用escape_javascript转义此输出。所以,虽然不是具体的解决方案,但我建议你试试:

$('#<%= @card_id %> .card-comments-title').html('<%= j show_number_of_comments(@node) %>');

答案 3 :(得分:1)

修改:对于Rails 3.1+,以下内容仅适用于

config.action_controller.include_all_helpers = false

DashboardHelper中包含DashboardController。您的.js.erb似乎属于CommentsController

您必须将助手方法移至ApplictionController或在您要使用的控制器中使用helper DashboardHelper包含帮助程序。

答案 4 :(得分:0)

您可以尝试pluralize

$('#<%= @card_id %> .card-comments-title').html('<%= pluralize(@comment_count, 'Comment') %>');

它应该在两个地方都有效。

我错过了你自己的跟进。

我建议将多个上下文中需要的帮助程序移动到application_helper.rb文件。也许不是最佳实践,但它可以完成这项工作。

答案 5 :(得分:0)

尝试使用j short for escape_javascript。

$('#<%= @card_id %> .card-comments-title').html('<%= j show_number_of_comments(@node) %>');