简体   繁体   English

如何通过 HAML 模板访问 Javascript 中的 ruby​​ 实例变量

[英]How to access ruby instance variable in Javascript through HAML template

I have a partial that is being rendered with the CommentsController.我有一个正在使用 CommentsController 呈现的部分。 Lets call this partial _edit_comment.html.haml where I'm passing in the instance variable @comment.让我们将这个部分称为 _edit_comment.html.haml,我在其中传入实例变量 @comment。

$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment', locals: { story: @comment.story, comment: @comment }) }')

In my partial, I have JS which I want to call when a button is clicked.在我的部分中,我有我想在单击按钮时调用的 JS。

= form_with model: [story.industry, story, comment], class: "w-100" do |f|
  %fieldset.w-100                                    
    = f.text_area :content, rows: 2, hide_label: true, class: 'px-2 py-1', placeholder: "Leave a comment" 
  %fieldset  
    = f.submit "Update", class: 'btn submit text-white mt-2'   
    %span.btn.cancel.text-white.mt-2 Cancel-
:javascript
  $(document).ready( function() {
    $('.cancel').click(e => {
      console.log("#{@comment}")       
    })
  } );

I understand that "#{}" works for strings but I want to be able to access the entire object instead.我知道“#{}”适用于字符串,但我希望能够访问整个对象。 Currently, the result of the console will be目前,控制台的结果将是

#<Comment:0x000055971a9c5278>

I need to get the entire ruby object because I want to pass it as a variable to another partial which will be rendered.我需要获取整个 ruby​​ 对象,因为我想将它作为变量传递给另一个将被渲染的部分。 Something like this:像这样的东西:

:javascript
  $(document).ready( function() {
    $('.cancel').click(e => {
      $("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment', locals: { story: "#{@comment}".story, comment: "#{@comment}" }) }')
    })
  } );

Is this possible?这可能吗?

To understand why you can't directly do what you're trying to do, it helps to think about the page-rendering process.要了解为什么您不能直接做您想做的事情,考虑一下页面呈现过程会有所帮助。 When your CommentsController controller renders a view, Rails processes your HAML template, which includes processing all your embedded Ruby (like string interpolation).当您的CommentsController控制器呈现一个视图时,Rails 会处理您的 HAML 模板,其中包括处理所有嵌入的 Ruby(如字符串插值)。 After that, though, your HTML is just HTML and your Javascript is just Javascript.但是,在那之后,您的 HTML 只是 HTML,而您的 Javascript 只是 Javascript。

So, in your case, Rails interpolates the "#{@comment}" at render time, but it's just a string when the Javascript executes in your browser, but you can't pass a Ruby object, etc. Likewise, escape_javascript and render are Rails view helpers, so they won't work when directly stuck into Javascript like that.因此,在您的情况下,Rails 在渲染时插入"#{@comment}" ,但是当 Javascript 在您的浏览器中执行时它只是一个字符串,但您不能传递 Ruby 对象等。同样, escape_javascriptrender是 Rails 视图助手,因此当像这样直接陷入 Javascript 时,它们将无法工作。 One good option, as @BKSpurgeon gives, is to render the edit partial in the original page and then just use a bit of plain JS to show/hide it.正如@BKSpurgeon 给出的那样,一个不错的选择是在原始页面中呈现编辑部分,然后只使用一些普通的 JS 来显示/隐藏它。

Another option is change your button to be a remote (ie, AJAX) link_to and then put your Javascript into a JS view.另一种选择是将您的按钮更改为远程(即 AJAX) link_to ,然后将您的 Javascript 放入 JS 视图中。 I don't really use HAML, but I think the link would be something like:我并没有真正使用 HAML,但我认为链接将类似于:

= link_to 'Cancel', edit_comment_path(@comment), remote: true 

And in edit_comment.js.haml :edit_comment.js.haml 中

:plain
$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment', locals: { story: "#{@comment}".story, comment: "#{@comment}" }) }')

(A quick google indicated that later versions of HAML might not require the :plain wrapper; perhaps someone with HAML experience can correct that if it's not quite right.) (一个快速的谷歌表明,更高版本的 HAML 可能不需要:plain包装器;也许有 HAML 经验的人可以纠正它,如果它不太正确。)

Consider using a nested form...or a similar variation考虑使用嵌套表单...或类似的变体

Here is a link to the rails guide: https://guides.rubyonrails.org/form_helpers.html#nested-forms这是 Rails 指南的链接: https : //guides.rubyonrails.org/form_helpers.html#nested-forms

It looks liked you want a nested form, and you want to edit comments, using the same form that is used when you want to edit a story (?) or story industry (?).看起来您想要一个嵌套表单,并且您想要编辑评论,使用的表单与您想要编辑故事 (?) 或故事行业 (?) 时使用的表单相同。 If that's the case then perhaps investigate using nested forms.如果是这种情况,那么也许可以使用嵌套表单进行调查。

Secondly, another gotcha to be aware of: you cannot place one HTML form inside another one: that can't be done.其次,要注意的另一个问题是:您不能将一个 HTML 表单放入另一个表单中:这是不可能的。 So the javascript workflow you are proposing must render the edit comment partial OUTSIDE the form you have above.........or you can employ a mix of javascript and use the nested forms method above using jquery/javascript.因此,您提议的 javascript 工作流程必须将编辑注释部分呈现在您上面的表单之外.........或者您可以混合使用 javascript 并使用上面使用 jquery/javascript 的嵌套表单方法。 Ryan Bates has devoted two excellent rails casts to this topic - here they are (1) and (2) : Ryan Bates 为这个话题专门做了两个优秀的 rails casts - 这里是(1)(2)

But to answer your question:但要回答你的问题:

...it can't be done like that ……不能那样做

I don't know if you can actually do it the way you were originally trying to do it - to pass complex ruby objects like that我不知道你是否真的可以按照你最初尝试的方式来做 - 像这样传递复杂的 ruby​​ 对象

...but there are solutions: ...但有解决方案:

(A) Render the partials and hide as needed (A) 根据需要渲染局部并隐藏

Why not try a different approach: render the partial directly in your html (but hide it from being seen by the user).为什么不尝试不同的方法:直接在你的 html 中渲染部分(但隐藏它不被用户看到)。

When the button is clicked, you can simply toggle the visibility of the already existing partial.单击按钮时,您可以简单地切换现有部分的可见性。

Since you're using jQuery:由于您使用的是 jQuery:

(B) Fetch the partial ayschronously (B) 异步获取部分

You can fetch the partial with request in your event handler - stimulus js does this type of workflow very well.您可以在事件处理程序中使用 request 获取部分 - 刺激 js 可以很好地完成这种类型的工作流程。 You can use the fetch API to get the html partial, or you can use AJAX if you want to support internet explorer etc.您可以使用 fetch API 来获取 html 部分,如果您想支持 Internet Explorer 等,也可以使用 AJAX。

...........you would have to decide whether you want the form nested, or you are happy with completely separate forms. .....您必须决定是要嵌套表单,还是对完全独立的表单感到满意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM