【问题标题】:Rails 3.1 - what is the best way to access controllers' variables in coffeescript?Rails 3.1 - 在咖啡脚本中访问控制器变量的最佳方法是什么?
【发布时间】:2011-12-15 04:58:29
【问题描述】:

我正在寻找一种将控制器的全局变量用于这样的咖啡脚本的方法:

控制器:

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()

这个想法是在一个页面中有几个commentables,并识别当前评论的一个隐藏/显示一个表单来评论它;表单的 id 是使用类和可注释的 id 构建的。此时,如果我尝试使用上面的代码访问一个元素,它不起作用,因为脚本中似乎不存在@commentable。

编辑:

我阅读了here的答案,并尝试了以下方法:

在我的帖子/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)

所以当用户点击链接添加评论时,它会隐藏之前的评论表单(如果有的话),它会显示新的正确表单,构建 cmets'container 的 id(例如 cmets_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_cmets_id 或其他...

【问题讨论】:

    标签: ruby-on-rails-3.1 coffeescript


    【解决方案1】:

    您可以使用coffeebeans 来完成。

    只需将其添加到您的 Gemfile 中:

    gem 'coffeebeans'
    

    然后根据需要创建文件:

    #app/views/posts/create.js.coffee
    $("#form_<%= @commentable.class %>_<%= @commentable.id %>").hide()
    

    【讨论】:

    • 这太棒了,它完全符合我的预期。只有一件事:上面的代码在我的情况下不起作用,因为要识别的 id 格式为#form_Post_3,所以我需要使用$("#form_&lt;%= @commentable.class %&gt;_&lt;%= @commentable.id %&gt;").hide(),而不使用#{}
    • 为了让它在 Heroku 上运行,我需要在我的 Gemfile 中添加 gem 'therubyracer'。
    【解决方案2】:

    如果您想在您的咖啡脚本文件中使用 erb,您必须将 erb 扩展名附加到文件中。所以你的文件应该重命名为create.js.coffee.erb。然后您可以执行以下操作:

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

    它应该可以正常工作。请参阅docs 了解更多信息。

    编辑

    我想我在你的问题中漏掉了一点。如果您想访问 js 文件中的实例变量,很遗憾您不能。有关详细信息,请参阅this 答案。

    【讨论】:

    • 我在阅读您的链接后更准确地编辑了这个问题。谢谢你的回复。
    • 这不是真的。提交远程表单时,不需要添加 erb 扩展。问问三南就知道了。 github.com/samnang/ajax_rails31_demo
    【解决方案3】:

    当您响应 js 时,这意味着它将 create.js.coffee 呈现为视图。您不需要在末尾添加.erb 以在里面使用erb 代码,如下所示:

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

    您可能对coffeescript 中的@ 感到困惑,它仅表示javascript 中的this.this#{ .. } 代码仅由咖啡脚本解释,而不是由 ruby​​ 解释(就像您在 HAML 中习惯的那样),因此您拥有的代码将在 javascript 中输出:

    $("#form_" + this.commentable["class"] + "_" + this.commentable.id).hide();
    

    【讨论】:

      猜你喜欢
      • 2011-11-08
      • 2016-02-21
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      • 2016-08-23
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多