代码之家  ›  专栏  ›  技术社区  ›  mediocre

在Ajax请求后基于模型中的值更新CSS类

  •  1
  • mediocre  · 技术社区  · 6 年前

    我有一个视图,其中显示了一个剧集列表。我用的是偏序词:

        <div class="episode-list">
          <% if user_signed_in? %>
            <%= render partial: "shared_partials/episode_with_image_compact", collection: @recent_episodes, as: :episode %>
        <% end %>
        </div>
    

    在这一部分中,我有一个按钮\u to,它向后端发送一个请求,将一个插曲标记为所见:

              <%= button_to manual_new_scrobble_path, {method: :post, form_class: 'manual-scrobble-btn', class: "button is-small #{'listened' if episode.has_play}", remote: true, params: {scrobble: {user_id: current_user.id, episode_id: episode.id}}} do %>
                <%= scrobble_icon(episode) %>
              <% end %>
    

    这个 scrobble_icon 函数只是根据事件的状态设置一个类,如下所示:

      def scrobble_icon(episode)
        if episode.has_play
          icon('fas', 'check', class: 'listened')
        else
          icon('fas', 'check', class: 'unlistened')
        end
      end
    

    remote: true 所以它不会导致页面加载。当我为SPA开发其他前端框架时,默认情况下总是有这种双向绑定,其中值将根据“store”/模型的状态进行更新。

    TurboLinks server generated javascript 但我还是想不出解决这个问题的正确方法。

    我想要的是:

    • 点击按钮
    • Button现在让类“被监听”

    实际发生的情况:

    • 请求成功并将值写入数据库
    • 按钮看起来一样

    很多类似问题的答案都是关于jQuery的,它是:


    2) 我不想在2019年使用

    谢谢您!

    0 回复  |  直到 6 年前
        1
  •  1
  •   arieljuod    6 年前

    1-查找元素

    首先,我要添加一些标识符,以便您可以识别正确的按钮

    <%= button_to manual_new_scrobble_path, {method: :post, form_class: 'manual-scrobble-btn', class: "button is-small #{'listened' if episode.has_play}", id: "button_for_episode_#{episode.id}", remote: true, params: {scrobble: {user_id: current_user.id, episode_id: episode.id}}} do %>
      <%= scrobble_icon(episode) %>
    <% end %>
    

    现在你可以用以下方法来解决这个问题:

    // find the button
    let button = document.getElementById("button_for_episode_#{params[:scobble][:episode_id]}");
    // add the class
    button.classList.add('listened');
    
    // find the icon within that button
    let icon = button.querySelector('.fas');
    // remove "unlistened" class
    icon.classList.remove('unlistened');
    // add "listened" class
    icon.classList.add('listened');
    

    此脚本应该是您正在调用的操作的视图。

        2
  •  1
  •   mediocre    6 年前

    arieljuod

    在你的 app/javascript/packs/application.js ajax:success 中提到的由Rails发送的事件 documentation .

    然后我们得检查一下 id 以区分来自其他来源的事件。然后我们添加/删除类,一切都按预期进行。

    到目前为止,它似乎工作良好,如果有什么我错过了请让我知道!

    document.addEventListener('ajax:success', function (event) {
        let detail = event.detail;
        let data = detail[0], status = detail[1], xhr = detail[2];
    
        // Check if our event is from an manual episode scrobble button
        let button = [...event.target.children].find(element => element.id === 'scrobble_btn_episode' + data.episode_id);
    
        // If find() is not successful it's undefined
        if (typeof button !== 'undefined') {
            // We set the classes on our button
            button.classList.add("listened");
            button.classList.remove("unlistened");
    
            // The button has a child, we also set the classes there for the check mark
            let id = button.getElementsByClassName('fa-check');
            id[0].classList.add("listened");
            id[0].classList.remove("unlistened");
        }
    });