RoR 和 json:按钮单击和更新计数不刷新

Posted

技术标签:

【中文标题】RoR 和 json:按钮单击和更新计数不刷新【英文标题】:RoR and json: No refresh on button click and updating count 【发布时间】:2020-11-22 05:57:47 【问题描述】:

我正在尝试在不刷新点击页面的情况下更改关注按钮。以下代码有效,但仅适用于我在视图中呈现的循环中的第一个帖子。其余的不会改变/工作。

在我看来

<% @tweets.reverse.each do |tweet| %>
...
<% if current_user.id != tweet.user.id %> 
        <% if current_user.following?(tweet.user) %>
          <%= link_to "Unfollow", relationships_path(user_id: tweet.user), data:  remote: true, type: :json, method: :delete , :class => "follow-btn btn btn-primary" %>
         <% else %>
           <%= link_to "Follow", relationships_path(user_id: tweet.user), data:  remote: true, type: :json, method: :post , :class => "follow-btn btn btn-primary" %>
        <% end %>
        <br>
       <% end %>
       <hr/>
      <% end %>
<% end %>

应用程序.js

$(document).on('ajax:success', '.follow-btn', function(event)
  let $el = $(this);
  let method = this.dataset.method;
  if (method === 'post') 
    $el.text('Unfollow');
    this.dataset.method = 'delete';
   else if (method === 'delete') 
    $el.text('Follow');
    this.dataset.method = 'post';
  
);

如何更新循环中指向同一用户的所有关注按钮?

这是更新的代码

application.js

$(document).on('ajax:success', '.follow-btn', function(event)
  let $el = $(this);
  let method = this.dataset.method;
  if (method === 'post') 
    $('.follow-btn[href="'+this.href+'"]').each(function(el) $(el).text('Unfollow');  );
    this.dataset.method = 'delete';
   else if (method === 'delete') 
    $('.follow-btn[href="'+this.href+'"]').each(function(el) $(el).text('Follow');  );
    this.dataset.method = 'post';
  
);

控制器

def create
    current_user.follow(@user)
    respond_to do |format|
      format.html
      format.json  head :created 
    end
  end

  def destroy
    current_user.unfollow(@user)
    respond_to do |format|
      format.html
      format.json  head :no_content 
    end
  end

这里的按钮仍然有效,但现在视图中没有改变。我怎样才能让它工作?

计数

在同一个视图上,但通过部分 (users/_search_users.html.erb) 呈现,我这样算。我怎样才能做到这一点,这样计数也不会在按钮单击时刷新页面?

<% @users.each do |user| %>
...
    <td stlye="padding:0 60px 0 60px;" col  align="right"><b><%= user.followers.count %> Followers</b></td>
<% end %>

我希望在不刷新的情况下在点击时更新按钮和计数。如果需要,我可以添加更多代码。

ty

【问题讨论】:

请避免同时提出多个问题。 谢谢!奇怪,由于某种原因它不起作用。该按钮有效,但现在视图上什么也没有发生。我看到它正在你的 sn-p 上工作。 【参考方案1】:

$(document).on('ajax:success', '.follow-btn', function(e) 
  // the JSON fetched
  let data = e.details[0];
  // the method we are changing to
  let method = this.dataset.method === 'post' ? 'delete' : 'post';
  // lookup table for the text
  let txt = 
    post: 'Follow',
    delete: 'Unfollow'
  [method];
  // loop through elements with the same href
  $(`.follow-btn[href="$this.getAttribute('href')"]`).each(function() 
    // change the attributes of the single node in the loop
    this.dataset.method = method;
    $(this).text(`$txt ($data.count)`);
  );
);

// This mocks the ajax call purely for the sake of this stacksnippets example.
// Do not include this in your actual implementation
$(document).on('click', 'a[data-remote]', function(e) 
  window.setTimeout(function() 
    let event = jQuery.Event('ajax:success');
    event.details = [ count: 5 , 'No Content'];
    $(e.target).trigger(event);
  , 25);
  e.preventDefault();
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <p>User 1</p>
  <a href="/follow/1" class="follow-btn" data-method="post" data-remote="true">Follow</a>
  <a href="/follow/1" class="follow-btn" data-method="post" data-remote="true">Follow</a>
</div>
<div>
  <p>User 2</p>
  <a href="/follow/2" class="follow-btn" data-method="post" data-remote="true">Follow</a>
  <a href="/follow/2" class="follow-btn" data-method="post" data-remote="true">Follow</a>
</div>

您可以使用render json: 在 JSON 响应中提供计数:

def create
    current_user.follow(@user)
    respond_to do |format|
      format.html
      format.json do
        render json:  count: @user.followers.count , 
               status: :created  
      end
    end
  end

def destroy
  current_user.unfollow(@user)
  respond_to do |format|
    format.html
    format.json do
        render json:  count: @user.followers.count , 
               status: :ok
    end
  end
end

我只是在猜测关联,因此请根据您的模型进行调整。

【讨论】:

谢谢,对于按钮的第一个 sn-p,我在控制台中收到错误“无法读取未定义的属性 '0'”? 这很奇怪。我修复了一个错误 - 需要使用 this.getAttribute('href') 而不是 this.href,因为后者返回绝对路径。 哦,我快到了,但仍然收到“无法读取属性 '0' 错误”。如果我忽略了按钮的计数,那么文本不会改变。 啊,对不起。它的e.detail。不是.details。不知道他们为什么在 Rails 5.1 中使用那个超级奇怪的签名。 guides.rubyonrails.org/… 是的,它只是一个字符串,您可以通过多种方式将其附加到 DOM。见api.jquery.com/append

以上是关于RoR 和 json:按钮单击和更新计数不刷新的主要内容,如果未能解决你的问题,请参考以下文章

删除后按后退按钮更新购物车计数

单击当前按钮时无法设置计数器

每当单击刷新按钮时,如何更新 iOS 应用程序包中的嵌入式 JSON 文件

反应:组件状态不更新记分员或计数器

如何在单击按钮时使用参数更新 DataTable?

计数按钮事件