如何通过 HAML 模板访问 Javascript 中的 ruby 实例变量
How to access ruby instance variable in Javascript through HAML template
我有一部分正在使用 CommentsController 呈现。让我们调用这个部分 _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}" }) }')
})
} );
这可能吗?
考虑使用嵌套形式...或类似的变体
这是 rails 指南的 link:https://guides.rubyonrails.org/form_helpers.html#nested-forms
您似乎想要嵌套表单,并且想要编辑评论,使用与编辑故事 (?) 或故事行业 (?) 时所用的相同表单。如果是这种情况,那么也许可以使用嵌套表单进行调查。
其次,另一个需要注意的陷阱:您不能将一个 HTML 表格放在另一个表格中:这是不可能的。因此,您提议的 javascript 工作流程必须在上面的表单之外呈现部分编辑评论......或者您可以混合使用 javascript 并使用嵌套表单方法以上使用 jquery/javascript。瑞安·贝茨 (Ryan Bates) 为这个主题投入了两个出色的 rails 演员 - 他们是 (1) and (2):
但是要回答你的问题:
...不能那样做
我不知道你是否真的可以按照你最初尝试的方式去做 - 像那样传递复杂的 ruby 对象
...但是有解决办法:
(A) 渲染部分并根据需要隐藏
为什么不尝试不同的方法:直接在您的 html 中渲染局部(但将其隐藏起来不被用户看到)。
单击该按钮后,您可以简单地切换已存在部分的可见性。
因为您正在使用 jQuery:
(B) 不同步地获取部分
您可以在您的事件处理程序中获取带有请求的部分 - stimulus js 可以很好地完成这种类型的工作流程。您可以使用 fetch API 获取 html 部分,或者如果您想支持 Internet Explorer 等,您可以使用 AJAX
......................您必须决定是要嵌套表单,还是对完全独立的表单感到满意。
要理解为什么您不能直接做您想做的事情,考虑一下 page-rendering 过程会有所帮助。当您的 CommentsController
控制器呈现视图时,Rails 处理您的 HAML 模板,其中包括处理所有嵌入的 Ruby(如字符串插值)。不过在那之后,你的 HTML 就是 HTML 而你的 Javascript 就是 Javascript.
所以,在你的情况下,Rails 在渲染时插入 "#{@comment}"
,但当 Javascript 在你的浏览器中执行时它只是一个字符串,但你不能通过Ruby 对象等。同样,escape_javascript
和 render
是 Rails 视图助手,因此当直接插入 Javascript 时它们将无法工作。正如@BKSpurgeon 给出的那样,一个不错的选择是在原始页面中呈现编辑部分,然后只使用一些普通的 JS 来 show/hide 它。
另一种选择是将您的按钮更改为遥控器(即 AJAX)link_to
,然后将您的 Javascript 放入 JS 视图中。我并没有真正使用 HAML,但我认为 link 会是这样的:
= link_to 'Cancel', edit_comment_path(@comment), remote: true
并且在edit_comment.js.haml中:
:plain
$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment', locals: { story: "#{@comment}".story, comment: "#{@comment}" }) }')
(快速 google 表明 HAML 的更高版本可能不需要 :plain
包装器;如果不完全正确,也许有 HAML 经验的人可以纠正它。)
我有一部分正在使用 CommentsController 呈现。让我们调用这个部分 _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}" }) }')
})
} );
这可能吗?
考虑使用嵌套形式...或类似的变体
这是 rails 指南的 link:https://guides.rubyonrails.org/form_helpers.html#nested-forms
您似乎想要嵌套表单,并且想要编辑评论,使用与编辑故事 (?) 或故事行业 (?) 时所用的相同表单。如果是这种情况,那么也许可以使用嵌套表单进行调查。
其次,另一个需要注意的陷阱:您不能将一个 HTML 表格放在另一个表格中:这是不可能的。因此,您提议的 javascript 工作流程必须在上面的表单之外呈现部分编辑评论......或者您可以混合使用 javascript 并使用嵌套表单方法以上使用 jquery/javascript。瑞安·贝茨 (Ryan Bates) 为这个主题投入了两个出色的 rails 演员 - 他们是 (1) and (2):
但是要回答你的问题:
...不能那样做
我不知道你是否真的可以按照你最初尝试的方式去做 - 像那样传递复杂的 ruby 对象
...但是有解决办法:
(A) 渲染部分并根据需要隐藏
为什么不尝试不同的方法:直接在您的 html 中渲染局部(但将其隐藏起来不被用户看到)。
单击该按钮后,您可以简单地切换已存在部分的可见性。
因为您正在使用 jQuery:
(B) 不同步地获取部分
您可以在您的事件处理程序中获取带有请求的部分 - stimulus js 可以很好地完成这种类型的工作流程。您可以使用 fetch API 获取 html 部分,或者如果您想支持 Internet Explorer 等,您可以使用 AJAX
......................您必须决定是要嵌套表单,还是对完全独立的表单感到满意。
要理解为什么您不能直接做您想做的事情,考虑一下 page-rendering 过程会有所帮助。当您的 CommentsController
控制器呈现视图时,Rails 处理您的 HAML 模板,其中包括处理所有嵌入的 Ruby(如字符串插值)。不过在那之后,你的 HTML 就是 HTML 而你的 Javascript 就是 Javascript.
所以,在你的情况下,Rails 在渲染时插入 "#{@comment}"
,但当 Javascript 在你的浏览器中执行时它只是一个字符串,但你不能通过Ruby 对象等。同样,escape_javascript
和 render
是 Rails 视图助手,因此当直接插入 Javascript 时它们将无法工作。正如@BKSpurgeon 给出的那样,一个不错的选择是在原始页面中呈现编辑部分,然后只使用一些普通的 JS 来 show/hide 它。
另一种选择是将您的按钮更改为遥控器(即 AJAX)link_to
,然后将您的 Javascript 放入 JS 视图中。我并没有真正使用 HAML,但我认为 link 会是这样的:
= link_to 'Cancel', edit_comment_path(@comment), remote: true
并且在edit_comment.js.haml中:
:plain
$("#edit-comment-#{object.id}").html('#{ escape_javascript(render :partial => 'edit_comment', locals: { story: "#{@comment}".story, comment: "#{@comment}" }) }')
(快速 google 表明 HAML 的更高版本可能不需要 :plain
包装器;如果不完全正确,也许有 HAML 经验的人可以纠正它。)