【问题标题】:Rails update element based on AJAX request?基于AJAX请求的Rails更新元素?
【发布时间】:2019-05-29 03:39:27
【问题描述】:

我已经阅读了很多关于 Rails 和 AJAX 以及 5.1 Unobtrusive javascript 的内容。它解释了很多关于使用 .js 文件响应 Rails 版本的 AJAX 调用的内容。

但是我想要做的不是提供整个 .js 文件,它只是在 <% link_to %> POST 请求之后更新一个元素。据我了解,设置 remote: true 将其作为 AJAX 请求提交。

基本上我有一个“帖子”,用户可以通过链接的“喜欢”按钮喜欢它。这会向“Post”控制器发送一个 POST 请求,该控制器将帖子更新为喜欢并添加喜欢的帖子。

不幸的是,看到被赞的帖子的效果(这只是链接改变颜色以及字体真棒图标),您需要刷新页面。我基本上希望它无需刷新即可更新。

我“认为”基于我所读到的内容,我需要创建一个respond do 并通过 .js 响应在我想要更新的视图中使用 .js 文件的请求(例如,如果控制器操作是被称为“喜欢”,也许是一个like.js.erb 文件即时更新?)。但我不想提供一个全新的页面。或者这只是运行 .js?

然后我可以做类似$('i.fa-icon#id').style.color = "blue" 之类的事情吗? (我假设我可以将数据从控制器发送到 .js.erb 文件?)。不确定执行此操作的最佳方法,不要经常使用某种 data-attribute 或其他东西(我仍然是这方面的初学者)。

【问题讨论】:

    标签: javascript ruby-on-rails ajax


    【解决方案1】:

    您的描述非常正确! 与另一个答案相反,您甚至不需要事件侦听器,但正如您所说,您希望在控制器中有一个 respond_to 。 所以从html开始:

    # post/index.html.erb
    <div id="like-button">
      <%= button_to "Like this post", post_path(@post), remote: true %>
    </div>
    

    请注意,当您使用 button_to 助手时,默认情况下它将是一个 POST 请求。

    如果你点击它,它会转到controller#update,你想把它改成这样:

    #posts_controller.rb
    ...
    def update
      @post.save
        respond_to do |format|
          format.html { redirect_to post_path(@post) } 
          format.js  # <-- will render `app/views/posts/update.js.erb`
        end
    end
    

    注意:format.html 是在禁用 JS 时呈现的。 现在在启用JS的场景中,它执行app/views/posts/update.js.erb文件。它可能看起来像这样:

    const likeButton = document.getElementById('like-button');
    likeButton.innerHTML = '<%= j render "posts/liked-link", post: @post %>';
    

    最后一行在做什么?当然,您可以直接使用 JavaScript 更改样式,但您也可以渲染一个新的部分 - 您将在一个新的 html 文件中创建:

    # app/views/posts/liked_link.html.erb
    <div id="like-button ">
     <p>"You liked this post!" </p>
    </div>
    

    我现在只是将链接/按钮更改为p,但当然你可以做任何你想做的事。

    希望这是有道理的:)

    【讨论】:

    • 哇,从来不知道button_to!我想每天都能学到新东西。顺便说一句,您发布的 js 文件的渲染链接中的“j”是什么?旁注:您将如何渲染新的局部?我假设与您在rails中的方式相同。只渲染 .js.erb 文件中的任何部分?
    • 因此,渲染渲染了view/posts/liked_link.html.erb 中的部分,它可以像我发布的最后一个代码sn-p一样短,因为它只会替换按钮的div。 j 正在转义“JavaScript 段的回车和单引号和双引号”api.rubyonrails.org/classes/ActionView/Helpers/… 但我在这里找到了更好的答案:stackoverflow.com/a/12518779/9595653
    • @Clara 感谢这篇精彩的帖子,让我更接近我想要完成的目标。我有一个独特的问题,我要更新的是一个大表中一个 的值。我无法弄清楚如何专门针对我需要更新的独特元素。如果我附加某种发送到控制器的 data-* 属性,有没有办法在 JS 响应中访问它?充其量元素的 ID 是动态的,我不知道如何定位正确的 ID。非常感谢任何帮助!
    • 你快到了。像这样为elememt分配一个动态数据属性:&lt;td data-record-id="&lt;%= record.id %&gt;"&gt;,然后在js.erb文件中查询它,就像document.querySelector("[data-record-id='&lt;%= @record.id %&gt;']")一样,因为在相应的控制器中你已经分配了这个实例变量(因为你知道,你是js因为你通过了控制器,所以文件得到了渲染)。希望对您有所帮助!
    【解决方案2】:

    不确定我是否理解这个问题,但如果你想更新喜欢按钮:

    您想要做的是向按钮添加一个事件侦听器,当单击它时,它会向处理喜欢的任何路由(使用正确的参数)发出 POST 请求,并且您的控制器应该用类似的对象(或其他在数据库中被存储)。在成功方法上发布您的帖子请求以获取“赞”按钮并将其更改为您想要的任何外观

    $(“#like-btn”).click(function(){ 
    Rails.ajax({
      url: "/some/url/to/like/controller",
      type: "post",
     data: [your post data],
      success: function(data) { $(`#${ data[“btn-name”] }`).attr(“color”, “blue”; }
    })    
    }
    

    你可以把这个脚本贴在html页面的底部

    您不必完全这样做,只是让您了解如何设置让 JavaScript 和 Ajax 处理发布请求和更新前端而不是使用 html 按钮的模式

    【讨论】:

    • 是的,基本上我想在 ajax 请求通过后更新按钮(例如更改颜色以表示用户喜欢该帖子)。所以这可以直接放在 .erb 文件中吗?
    • 是的,它只是一个脚本,你可以将它放在 erb 文件中(在
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签