Rails 3.1 - как лучше всего получить доступ к переменным контроллеров в coffeescript? - PullRequest
1 голос
/ 11 декабря 2011

Я ищу рецепт, чтобы использовать глобальные переменные контроллера в coffeescript, как это:

Контроллер:

respond_to :js

def create
  @commentable = commentable
  @comment = @commentable.comments.build({:comment => params[:comment], :user => current_user})
  @comment.save
  respond_with(@comment, @commentable)
end

create.js.coffee:

$("#form_#{@commentable.class}_#{@commentable.id}").hide()

Идея состоит в том, чтобы иметь несколько комментариев на одной странице и идентифицировать тот, который в настоящее время комментируется, чтобы скрыть / показать форму для комментирования; идентификатор формы строится с использованием класса и идентификатора комментируемого. В настоящее время, если я пытаюсь получить доступ к элементу с кодом выше, он не работает, потому что @commentable, кажется, не существует в сценарии.

EDIT:

Я прочитал ответ здесь , и я попробовал следующее:

В моих сообщениях / show.haml

:javascript
  var commentable_comments_id;
#post
  @post.body
= render :partial => 'comments/list', :locals => {:commentable => @post}

В моем частичном _list.haml

#comments_container
  %div{:id => "comments_#{commentable.class}_#{commentable.id}"}
    - commentable.comments.reverse_each do |comment|
      = render :partial => 'comments/comment', :locals => {:comment => comment}
  - if current_user
    .add_comment_link{:id => "link_#{commentable.class}_#{commentable.id}"}
      #{link_to "Commenter"}
    .add_comment{:id => "form_#{commentable.class}_#{commentable.id}"}
      = render :partial => 'comments/comment_form', :locals => {:commentable => commentable}

И в частичном _comment_form.haml

.comment_form
  = form_tag polymorphic_path([commentable, Comment]) , :method => :post, :remote => true do |f|
    .comment_field
      = text_area_tag :comment, params[:comment], :id =>"comment_area", :rows => 4, :cols => 50
    .comment_field 
      = submit_tag "Commenter", :id => "submit_comment_#{commentable.class}_#{commentable.id}", :class => "submit_comment"

В posts.js.coffee:

jQuery ->

  commentable_link_id = null
  commentable_form_id = null

  hide_element_by_id = (id_name) ->
    $("#"+id_name).hide()
  show_element_by_id = (id_name) ->
    $("#"+id_name).show()

  $('.add_comment_link').click ->
    currentId = $(this).attr('id')
    if(commentable_link_id != null && commentable_form_id != null)
      hide_element_by_id(commentable_form_id)
      show_element_by_id(commentable_link_id)

    commentable_link_id = currentId
    commentable_form_id = currentId.replace("link", "form")    
    hide_element_by_id(commentable_link_id)
    show_element_by_id(commentable_form_id)

    commentable_comments_id = currentId.replace("link", "comments")   
    false

  $('.submit_comment').click -> 
    if(commentable_link_id != null && commentable_form_id != null)
      hide_element_by_id(commentable_form_id)
      show_element_by_id(commentable_link_id)

Таким образом, когда пользователь нажимает на ссылку, чтобы добавить комментарий, он скрывает предыдущую форму комментария (если есть), показывает новую правильную форму, создает идентификатор контейнера комментариев (например, comments_Post_3) и сохраняет его. в глобальной переменной js страницы:

commentable_comments_id = currentId.replace("link", "comments")

Затем в create.js.coffee я пытаюсь добавить новый комментарий в сохраненный контейнер, используя эту переменную:

$('<%= escape_javascript(render(:partial => @comment))%>')
  .appendTo("#"+commentable_comments_id)
  .hide()
  .fadeIn()

Я думаю, что это не правильно, потому что последняя операция (добавление с замиранием) не работает, поэтому глобальная переменная commentable_comments_id не должна инициализироваться или что-то еще ...

Ответы [ 3 ]

2 голосов
/ 14 декабря 2011

Вы можете сделать это, используя coffeebeans .

Просто добавьте его в свой Gemfile:

gem 'coffeebeans'

А затем создайте файл, как хотите:

#app/views/posts/create.js.coffee
$("#form_<%= @commentable.class %>_<%= @commentable.id %>").hide()
0 голосов
/ 14 декабря 2011

Когда вы отвечаете на js, это означает, что create.js.coffee отображается как представление. Вам не нужно , чтобы добавить .erb в конец, чтобы использовать внутри себя код erb, например:

$("#form_<%=@commentable.class%>_<%=@commentable.id>").hide()

Вы, вероятно, смущены @ в coffeescript, это просто означает this. или this в javascript. И код #{ .. } интерпретируется только coffeescript, а не ruby ​​(как вы привыкли в HAML), поэтому код, который у вас есть, выведет это в javascript:

$("#form_" + this.commentable["class"] + "_" + this.commentable.id).hide();
0 голосов
/ 13 декабря 2011

Если вы хотите использовать erb в ваших файлах coffeescript, вы должны добавить расширение erb к файлу.Таким образом, ваш файл должен быть переименован в create.js.coffee.erb.И тогда вы можете сделать что-то вроде:

$ ->
  alert('<%= Post.first.name %>')

Это должно работать нормально.См. документы для получения дополнительной информации.

РЕДАКТИРОВАТЬ

Я думаю, что упустил пункт в вашем вопросе.Если вы хотите получить доступ к переменным экземпляра в ваших js-файлах, к сожалению, вы не сможете .См. этот ответ для получения дополнительной информации.

...