2015-07-15 3 views
12

У меня есть вспомогательный метод в моем dashboard_helper.rb который выглядит следующим образом:Как выполнить вспомогательный метод из JS ERB?

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'); 

Проблема с последним в том, что он не обрабатывает плюрализацию.

Каков наилучший способ приблизиться к этому?

Edit 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> 

Edit 2

Иногда это просто терпит неудачу. Он не выводит никаких ошибок ни на консоль, ни на мой серверный журнал, она просто заменяет .card-comments-title пустым значением.

+0

Pure JS подхода дает развязана логике из представления, вы пробовали его все же? – Anatoly

+0

Что означает «это не работает», точно? Вы получаете неопределенную ошибку метода? – amiuhle

+0

В вашем представлении HTML вы вызываете вспомогательный метод с 'node', в JS вы вызываете его с помощью' @ node'. – amiuhle

ответ

5

Итак, я понял, что я хотел бы сделать в своем конкретном случае, то есть умножить количество комментариев в моем JS ERB, но я не понял, как использовать helper_method из моего JS ERB - так что этот ответ не " t действительно ответить на этот вопрос.

Однако я документирую это здесь, если у кого-то есть аналогичная проблема, и мое решение помогает им.

В моем JS ERB все, что я сделал, было использовано методом Rails pluralize. Я полностью забыл об этом, пока не набрал этот вопрос, и он работает как шарм.

Вот фрагмент кода для моего create.js.erb:

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

работает как шарм, но это еще не ответ на мой вопрос о ссылке/с помощью вспомогательных методов здесь.

+2

im not sure, если это ответили или нет. просто хочу ответить, потому что теперь мне любопытно, как мои помощники работают для меня в js.erb. я думаю, что ваш @node не должен быть доступен в вашем создании.js.erb, поэтому он не работает для вас. даже если вы вызываете pluralize, pluralize все еще является вспомогательным методом, который вызывается. если ваш «@node» отсутствует, узел node.comments_count должен сбой. – Athar

+1

Да, помощники могут определенно быть вызваны в erb, не имеет значения, является ли это 'js' или' html'. Я думаю, что так же, как @Athar: '@ node' был, скорее всего, ноль. – nathanvda

+0

@Athar Я считаю, что у вас может быть правильный ответ. Напишите это как ответ, и я приму это. Вы правы, потому что 'pluralize' действительно работает (это помощник Rails). – marcamillion

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) %>'); 
+0

Я попытался убежать, используя 'escape_javascript', но не кубики. – marcamillion

+0

Кроме того, лучший способ добиться этого - просто использовать вспомогательный метод Rails 'pluralize', который использует I18n, я считаю. Когда я пытаюсь выполнить 'console.log (« @ Node: <% = j show_number_of_comments (@node)%> ");' который печатает: '@Node: 8 комментариев', где' 8' - количество комментариев Перед тем, как я представил эту последнюю, так теоретически, что нужно выплевывать «... 9 комментариев», а не «8». – marcamillion

+0

i18n добавил 'pluralize' еще не был выпущен! Это только на [главная ветвь] (https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/text_helper.rb#L228), а не на [4.2 stable] (https://github.com/rails/rails/blob/4-2-stable/actionview/lib/action_view/helpers/text_helper.rb#L215). Следующее теоретическое поведение, которого вы ожидаете, не происходит, потому что вы уже запросили '@ node' раньше. Если вы переназначите '@ node' с запросом, вы получите' 9 комментариев'. – vee

4

Вы также можете попытаться избежать использования бэкенда, если не требуется локализации:

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); 
+0

Это интересный подход, но не совсем ответ на то, что я хотел знать re: вспомогательный метод. – marcamillion

0

Вы можете попробовать pluralize:

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

Он должен работать в обоих местах.

Я пропустил ваше собственное наблюдение.

Я бы предложил перемещать помощников, которые вам нужны в нескольких контекстах, в файл application_helper.rb. Возможно, это не самая лучшая практика, но она будет выполнять эту работу.

0

Попробуйте использовать j short для escape_javascript.

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

Это не работает для меня. – marcamillion

+0

Что возвращает 'Object.const_defined? (« DashboardHelper »)? – daslicious

+0

Он возвращает 'true', когда помещается в' console.log ("<% = Object ...") '. – marcamillion

1

Edit: Для Rails 3.1+, следующее только справедливо, если

config.action_controller.include_all_helpers = false 

Ваш DashboardHelper включен в DashboardController. Ваш .js.erb, кажется, принадлежит к чему-то вроде CommentsController.

Вы должны либо переместить вспомогательный метод к вашим ApplictionController или включить помощник, используя helper DashboardHelper в контроллере вы хотите использовать его.

+0

Хорошо, это не похоже на рельсы 4 больше ... – amiuhle

+0

Что не работает? «Config.action_controller ...» или тот факт, что код в «DashboardHelper» включен только в «DashboardController»? Я чувствую, что ты можешь быть здесь. – marcamillion

+0

Согласно документам, в Rails 3.1 и более поздних версиях все помощники включены по умолчанию. Но только из любопытства, что произойдет, если вы дублируете помощника в 'CommentsController'? – amiuhle