问题描述
我有一个正在用CommentController渲染的局部图像。让我们称其为_edit_comment.html.haml部分,我在其中传递实例变量@comment。
$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment',locals: { story: @comment.story,comment: @comment }) }')
在我的部分中,我有一个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}")
})
} );
我知道“#{}”适用于字符串,但是我希望能够访问整个对象。目前,控制台的结果为
#<Comment:0x000055971a9c5278>
我需要获取整个ruby对象,因为我想将其作为变量传递给将要呈现的另一部分。像这样:
:javascript
$(document).ready( function() {
$('.cancel').click(e => {
$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment',locals: { story: "#{@comment}".story,comment: "#{@comment}" }) }')
})
} );
这可能吗?
解决方法
要了解为什么您不能直接执行您要执行的操作,请考虑一下页面呈现过程。当CommentsController
控制器呈现视图时,Rails处理您的HAML模板,其中包括处理所有嵌入式Ruby(例如字符串插值)。不过,在那之后,您的HTML就是HTML,您的Javascript就是Javascript。
因此,在您的情况下,Rails在渲染时对"#{@comment}"
进行插值,但是当Javascript在您的浏览器中执行时,它只是一个字符串,但是您不能传递Ruby对象,等等。类似地,{{ 1}}和escape_javascript
是Rails视图的助手,因此当它们直接插入Javascript时它们将无法工作。正如@BKSpurgeon所给出的,一个不错的选择是在原始页面中呈现部分编辑内容,然后仅使用一些普通的JS来显示/隐藏它。
另一种选择是将按钮更改为远程(即AJAX)render
,然后将Javascript放入JS视图。我并不是真的使用HAML,但是我认为链接类似于:
link_to
并在 edit_comment.js.haml 中:
= link_to 'Cancel',edit_comment_path(@comment),remote: true
(一个快速的Google表示,HAML的更高版本可能不需要:plain
$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment',locals: { story: "#{@comment}".story,comment: "#{@comment}" }) }')
包装器;如果不太正确,也许有HAML经验的人可以纠正它。)
考虑使用嵌套表格...或类似的变体形式
以下是Rails指南的链接:https://guides.rubyonrails.org/form_helpers.html#nested-forms
看起来您想要一个嵌套表单,并且想要使用与编辑故事(?)或故事行业(?)所使用的表单相同的表单来编辑注释。如果是这种情况,那么也许可以使用嵌套表单进行调查。
第二,要注意的另一个陷阱:您不能将一个HTML表单放在另一个HTML表单中:无法完成。因此,您提出的javascript工作流必须部分地将编辑注释部分呈现为上面具有的形式.........或者您可以混合使用javascript,并使用上面的jquery / javascript嵌套形式方法。瑞安·贝茨(Ryan Bates)为此主题专门制作了两个出色的剧本-这里是(1)和(2):
但要回答您的问题:
...不能那样做
我不知道您是否真的可以按照最初尝试的方式进行操作-传递像这样的复杂红宝石对象
...但是有解决方案:
(A)渲染部分并根据需要隐藏
为什么不尝试其他方法:直接在您的html中渲染部分内容(但将其隐藏起来,以防止用户看到)。
单击按钮后,您只需切换已存在的局部的可见性即可。
由于您使用的是jQuery:
(B)异步获取部分
您可以在事件处理程序中获取带有请求的局部消息-刺激js很好地完成了这种类型的工作流程。您可以使用fetch API来获取html部分,或者,如果您要支持Internet Explorer等,则可以使用AJAX。
.........您必须决定是要嵌套表格,还是对完全独立的表格感到满意。