Rails中如何实现button_to随banlist状态动态隐藏与显示?
解决按钮显示/隐藏的问题
我来帮你搞定这个按钮的显示隐藏逻辑,核心问题在于你现在的create动作里用了跳转,没法做局部DOM操作,咱们一步步来改:
1. 调整RadAcctsController的create方法
首先把JS响应改成渲染模板,而不是跳转,这样才能操作页面上的按钮:
def create @rad_acct = Banlist.new(rad_acct_params) respond_to do |format| if @rad_acct.save format.html { redirect_to @rad_acct, notice: 'Banlist was successfully created.' } format.json { render :show, status: :created, location: @rad_acct } # 把当前操作的用户名传给JS模板 format.js { @username = params[:username] } else format.html { render :new } format.json { render json: @rad_acct.errors, status: :unprocessable_entity } format.js { @error = true } end end end
2. 创建create.js.erb模板处理按钮隐藏
在app/views/rad_accts目录下新建create.js.erb文件,用来定位并隐藏点击的按钮:
<% if @error %> alert('Failed to ban this user.'); <% else %> // 找到包含目标用户名的行,然后隐藏里面的提交按钮 $('tr:contains("<%= j @username %>")').find('input[type="submit"]').hide(); <% end %>
这里用j方法转义用户名,避免特殊字符导致JS报错。
3. 页面加载时就判断是否显示按钮
修改index.html.erb,页面渲染时先检查用户是否已经在banlist里,已ban的就不显示按钮,同时给按钮加个唯一类名方便后续操作:
<% @rad_accts.each do |rad_acct| %> <tr class="gradeX"> <td><%= rad_acct.username %></td> <td> <% unless Banlist.exists?(username: rad_acct.username) %> <%= button_to 'Ban', { controller: "rad_accts", action: "create", username: rad_acct.username }, method: :post, data: { confirm: 'Are you sure?' }, remote: true, class: "ban-btn-#{rad_acct.username}" %> <% end %> </td> </tr> <% end %>
4. 处理删除ban用户后的按钮恢复
接下来要处理删除banlist用户后按钮重新显示的逻辑,先调整banlists_controller的destroy方法:
def destroy @banlist = Banlist.find(params[:id]) @username = @banlist.username @banlist.destroy respond_to do |format| format.html { redirect_to banlists_url, notice: 'Banlist was successfully destroyed.' } format.json { head :no_content } format.js # 渲染destroy.js.erb end end
然后在app/views/banlists目录下新建destroy.js.erb文件:
// 通过唯一类名找到对应按钮并显示 $('.ban-btn-<%= j @username %>').show();
这样就完成了所有逻辑:
- 页面加载时,已被ban的用户不会显示Ban按钮
- 点击Ban按钮后,无需刷新页面,按钮直接隐藏
- 在banlist页面删除用户后,对应RadAccts页面的按钮会自动重新显示
内容的提问来源于stack exchange,提问作者Cenk
相关产品推荐
相关产品推荐

