Rails Action Cable 评论提交后输入框未清空及keyCode适配问题
问题排查:回车提交评论输入框异常问题
问题背景
原有代码运行正常,后收到VS Code提示event.keyCode已废弃,适配修改后出现两个异常:
- 回车提交或手动点击提交按钮后,输入框内容无法清空
- 改用
$('#comment_field').val('')清空输入框时,回车提交后台完全收不到输入值,仅手动点击按钮可正常提交
原有代码(使用已废弃的event.keyCode)
consumer.subscriptions.create("CommentsChannel", { connected() { // Called when the subscription is ready for use on the server }, disconnected() { // Called when the subscription has been terminated by the server }, received(data) { console.log(data.content) $('#comments').append('<strong>' + data.content[1] + ': ' + '</strong>' + data.content[0] + ' ' + data.content[2] + ' <hr class="comments-hr">' ) // Called when there's incoming data on the websocket for this channel } }); var submit_messages; $(document).on('turbolinks:load', function() { submit_messages() }) submit_messages = function (){ $('#new_comment').on('keydown', function (event){ if(event.keyCode === 13){ $('#send_button').click() event.target.value = '' event.preventDefault() } }) }
适配废弃提示后的修改代码
submit_messages = function (){ $('#new_comment').on('keydown', function (event){ if(event.key === 'Enter'){ $('#send_button').trigger( "click" ) event.target.value = '' event.preventDefault() } })
相关配套代码
1. 模型层方法
def self.post_comment(new_comment,ticket,user) ticket.comment.tap do |post_new_comment| post_new_comment.content << new_comment post_new_comment.username << user post_new_comment.sendtime << Time.now if post_new_comment.save ActionCable.server.broadcast 'comments_channel', content: [new_comment, user, Time.now.strftime("%H:%M:%S")] end end end
2. 输入框ERB代码
<%= f.text_field :comment, class: "form-control", placeholder: "Write a Comment", id: "comment_field" if @ticket.status%>
3. 提交按钮Helper代码
def submit_comment_button content_tag(:button, class: "btn btn-sm btn-primary", id: "send_button") do content_tag(:i, class: "bi bi-arrow-right-square") do end end end
问题原因
- 输入框无法清空:keydown事件绑定在表单
#new_comment上,触发回车时event.target指向的是表单本身而非输入框#comment_field,所以event.target.value = ''没有作用到实际输入元素上。 - 回车提交后台收不到值:清空输入框的操作执行顺序早于提交逻辑,js同步执行时,提交请求还没获取输入值,输入框就已经被清空,导致提交的是空内容。
可行解决方案
方案1:直接调整前端逻辑(实现简单)
调整清空操作的顺序,同时绑定手动点击的清空逻辑:
submit_messages = function (){ $('#new_comment').on('keydown', function (event){ if(event.key === 'Enter'){ event.preventDefault() // 先触发提交 $('#send_button').trigger("click") // 再清空指定输入框,避免event.target指向错误 $('#comment_field').val('') } }) // 补充手动点击按钮的清空逻辑 $('#send_button').on('click', function() { $('#comment_field').val('') }) }
方案2:绑定广播回调清空(更稳妥,避免提交失败丢失内容)
在ActionCable收到后台成功保存的广播后再清空输入框,保证只有提交成功才清除内容:
consumer.subscriptions.create("CommentsChannel", { connected() { // Called when the subscription is ready for use on the server }, disconnected() { // Called when the subscription has been terminated by the server }, received(data) { console.log(data.content) $('#comments').append('<strong>' + data.content[1] + ': ' + '</strong>' + data.content[0] + ' ' + data.content[2] + ' <hr class="comments-hr">' ) // 收到广播确认提交成功后清空输入框 $('#comment_field').val('') } });
内容的提问来源于stack exchange,提问作者kostasew
相关产品推荐
相关产品推荐

