You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

扑克站点实现淘汰玩家时更新MongoDB状态的技术求助

解决扑克玩家淘汰状态更新的问题

看起来你的代码里有几个关键问题导致更新功能无法正常工作,我来帮你一步步修正:

1. 修正PUT路由的核心问题

你的PUT路由现在缺少玩家ID参数,而且findByIdAndUpdate的参数逻辑也不对。我们需要调整这两部分:

  • 把路由路径改成/seating/:id,这样才能获取到要淘汰的玩家唯一标识
  • 明确指定更新字段为{ inTournament: "No" },不需要从参数里动态获取这个值,因为淘汰动作就是固定把状态改成"No"

修正后的app.js路由代码:

// 先确保你已经引入并启用method-override中间件(否则PUT请求会被识别为POST)
const methodOverride = require('method-override');
app.use(methodOverride('_method'));

// 原有的seating GET路由保持不变
app.get("/seating", function(req, res){
  Seat.find({inTournament: "Yes"}, function(err, allseats){
    if(err){
      console.log(err);
    } else {
      shuffle(allseats);
      res.render("seating", {seats: allseats});
    }
  });
});

// 更新后的PUT路由
app.put("/seating/:id", function(req, res){
  Seat.findByIdAndUpdate(
    req.params.id, 
    { inTournament: "No" }, // 固定设置淘汰状态
    function(err, updatedStatus){
      if(err) {
        console.log(err);
        res.redirect("/seating"); // 出错时重回座位页面
      } else {
        res.redirect("/seating"); // 更新成功后刷新页面,让玩家列表自动更新
      }
    }
  );
});

2. 修正视图中的表单问题

你的表单存在两个小错误:action路径拼写缺了=,而且没有传递当前玩家的ID。我们需要把玩家的_id嵌入到表单的action路径中,这样路由才能定位到要更新的对象。

修正后的视图代码片段:

<div class ="row text-left" style="display:flex; flex-wrap: wrap;">
  <div class="col-md-4 table table-bordered">
    <h3 class="text-center">Table 1</h3>
    <ol>
      <% var i = 1; %>
      <% seats.forEach(function(seat){%>
        <% if(seat.player && i < perTable1){%>
          <li>
            <%= seat.player %>
            <!-- 修正action路径,添加当前seat的_id -->
            <form action="/seating/<%= seat._id %>?_method=PUT" method="POST">
              <button class="btn btn-sm btn-warning" type="Submit">Eliminate</button>
            </form>
          </li>
          <% i++ %>
        <% } %>
      <% }); %>
    </ol>
  </div>
</div>

额外注意事项

  • method-override依赖:如果还没安装这个包,先运行npm install method-override,否则?_method=PUT的转换不会生效,服务器会把请求当成普通POST处理。
  • 简化循环逻辑:你原来的循环里用seats[j].player其实没必要,直接用forEach回调里的seat.player就可以,代码更简洁易读。
  • 重定向优化:原来的res.send("Data Updated")会返回纯文本,改成res.redirect("/seating")能让页面自动刷新,用户可以直接看到淘汰后的玩家列表变化。

这样修改后,点击「Eliminate」按钮时,对应玩家的inTournament字段就会被正确更新为"No",页面也会自动刷新,该玩家会从参赛列表中消失。

内容的提问来源于stack exchange,提问作者J.Wenthur

火山引擎 最新活动