如何从以前的 JS 状态中保留“this”并将其转移到另一个状态?

Posted

技术标签:

【中文标题】如何从以前的 JS 状态中保留“this”并将其转移到另一个状态?【英文标题】:How do I preserve the `this` from a previous JS state and transfer it to another? 【发布时间】:2015-09-30 01:56:53 【问题描述】:

所以我有一个带有 simple_form 的视图,如下所示:

<%= simple_form_for([node, Comment.new], html:  id: "new_comment_card-#@card_number", remote: true) do |f| %>
        <%= f.error_notification %>
        <%= f.input_field :message, as: :text, id: "card-input-field-#@card_number", class: "input-field", placeholder: "Share your thoughts", cols: "30", rows: "10" %>
        <%= f.button :submit %>
<% end %>

此表单在同一视图中出现多次,因此指定了动态id

当按下该按钮时,一些 JS 会像这样拦截提交(以确保提交为正确的表单发送正确的凭据):

  $(".input-submit").click(function(event) 
      event.preventDefault();
      $(this).closest('form').submit();
  );

否则有时会提交最后呈现的表单,这会导致各种问题。

提交后,最终会导致CommentsController#Create,如下所示:

  def create
    @node = Node.find(params[:node_id])
    @comment = current_user.comments.new(comment_params)
    @comment.node = @node

    respond_to do |format|
      if @comment.save and @node.save
        format.html
        format.js
      else
        format.html
        format.js
      end
    end
  end

然后查找并执行 - create.js.erb。我希望我的create.js.erb 做 3 件事:

    将新保存的评论添加到当前div#id=card-comments 的顶部,可能带有小动画来显示新评论。 下推现有 cmets 的另一个列表,为步骤 1 中新创建的评论让路。 从输入字段中删除文本,这样用户就可以在不刷新的情况下添加另一条评论,也许需要一点点抖动/突出显示/动画。

我不确定如何实现这一点 - JS 不是我的强项。

我在create.js.erb 中尝试过这样做,但我有各种奇怪的行为,包括将一张卡上的 cmets 的全部内容复制到另一张卡上的 cmets:

$('#card-comments').append("<%= j (render partial: 'nodes/comment', collection: @node.comments) %>");

我如何实现上述目标?

【问题讨论】:

你确定“最后呈现的表单会被提交”吗?对我来说听起来不太可能(如果表单没有嵌套并且具有唯一的 id) 现在我想起来了,我敢打赌重复的 id。 @SergioTulentsev 是的,我相信重复的 id 是问题所在 - 我只是不知道如何解决它。我有具有唯一 ID 的 div,cmets 居住在其中。每个评论块都存在于 .card-comments 类中,但它是具有唯一 ID &lt;div class="card" id="card-&lt;%= @card_number %&gt;"&gt; 的 div 的子项。所以,我可以定位那个 div,但问题是……我怎么知道要定位哪个 ID?即任何时候页面上都会呈现 10 张卡片,我如何将评论刚刚添加到 card-3 的事实传递给 create.js.erb。这就是我正在努力解决的问题。 很简单,只需在表单参数中添加card_id=3(例如作为隐藏字段)。这样您就可以知道要在 .js.erb 文件中使用的 id。 【参考方案1】:

如果用户可以在页面上的多张卡片上提交 cmets,它应该向控制器提交一个参数,表明评论是在哪张卡片上提交的,并且 JS 应该替换 该特定卡片的 cmets .当前,您的 jQuery 选择器位于与特定卡片不匹配的 #card-cmets 上。或许将 cmets 放在具有类似于表单的特定 ID 的 div 中,并替换该 div 的所有 cmets

$('#card-<%= params[:node_id] %>-comments').html("<%= j (render partial: 'nodes/comment', collection: @node.comments) %>");

【讨论】:

这正是我想要做的,但我不确定如何在create.js.erb 中做到这一点。每张卡都有一个唯一的 ID,即card-1, card-2, etc.。问题是,我如何获取最近创建的评论,并将其从 create.js.erb 中添加到当前卡片中。你有可以给我看的代码示例吗?

以上是关于如何从以前的 JS 状态中保留“this”并将其转移到另一个状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何自动检测已登录的用户并将其转至仪表板页面,而无需再在Ionic 4和firebase中登录

如何使用 Node.js 通过 ffmpeg 流式传输 MP4 文件?

页面重定向后未保留 Vuex 状态

C#如何保留datagridview中的原来数据并将新的数据添加到datagridview中?

Extjs 如何使网格列标题菜单选项保留在 Cookies 中(有状态)

使用 jQuery 可排序时如何保留原始列表项