【问题标题】:Populating a table with ng-repeat and conditionals使用 ng-repeat 和条件填充表
【发布时间】:2026-02-12 09:40:02
【问题描述】:

我是 Angular 的新手(2 周大),我无法理解表格的正确实现,其中填充了来自 $scope 的数据。

更具体一点。我有一张表,我用硬编码的时间数组填充(即[{ "time": "8:00 - 8 - 30"},...):

<table class="table table-hover">
    <thead>
    <tr>
        <th>Time</th>
        <th>Status</th>
        <th>Contact Person</th>
    </tr>
    </thead>
     <tbody>
      <tr ng-repeat="time in times" style="cursor:pointer">
        <td> {{time.time}}
       </td>
          <td>

              <button type="button" class="btn btn-info btn-lg" ng-click="open(time.time)">Open</button>

          </td>
          <td>---</td>
      </tr>
    </tbody>
  </table>

我还有另一个 $scope 元素,其中包含一个名为 $scope.reservations 的对象数组。模型中的数据如下所示:

我试图做的是在第二列(状态)中放置一个条件,如果$scope.reservations.timeSlot == {{time.time}},则显示特定的div(在这种情况下,div 会说“这个空间已经采取)。否则,继续显示标有“打开”的按钮。

此条件也将用于下一列(联系人),如果$scope.reservations.timeSlot == {{time.time}},则显示div$scope.reservations.NetID。否则,继续显示“---”。

我知道我必须以某种方式将ng-repeat 与另一个ng-repeat 嵌套,可能还有ng-show?但我正在努力思考完成此任务的正确语法。有人知道完成填充这样一个表的最佳方法吗?

更新:这是我为重现问题而创建的一个 plunker:example Plunker

我们将不胜感激任何帮助,如果您对我有任何问题或疑虑,请随时提出。我希望能够实现这一点,并真正了解发生了什么。希望大家今天过得愉快!

【问题讨论】:

  • 在我看来,您在客户端的信息太多了。除非你想展示它,否则确认代码不应该在客户端(你的描述听起来不对)
  • plnkr 总是有助于重现并以更简洁的方式说明您的问题
  • @Yaron U. 你是对的,目前我在 $scope.reservations 中有太多信息。我有来自 mongodb 的信息,并且还没有在 db.collection.find() fetch 上添加一个投影。一旦可以正确显示,我将减少返回的数据量,并清除不需要的数据。

标签: javascript html angularjs json


【解决方案1】:

在您的情况下,最好的解决方案是在您呈现之前处理您收到的数据(当您从服务器获取数据时或在将其发送到客户端之前在服务器上)

如果您的数据如下所示:

$scope.times = [{
   "time": "8:00-8:30",
   "reservation":null
},{
   "time": "8:00-8:30",
   "reservation": {
       "_NetId": "1234567"
   }
}]

然后你可以做类似的事情

...
  <tr ng-repeat="time in times" style="cursor:pointer">
    <td> {{time.time}}
   </td>
      <td>

          <button type="button" class="btn btn-info btn-lg" ng-click="open(time.time)">Open</button>

      </td>
      <td>
         <span ng-if="!time.reservation">---</span>
         <span ng-if="!!time.reservation">{{time.reservation.NetId}}</span>
      </td>
  </tr>
...

【讨论】:

  • 我同意如果我将 Times 表数据与实际预订数据结合起来会更容易。这个应用程序最终将包含 socket.io。鉴于这些知识,您认为您的解决方案是否最好在可能是 angularjs 服务中进行这种类型的数据格式化,然后推送到客户端(如您在此处演示的那样)?我只是想确保在我知道会发生频繁更新的情况下以最佳方式进行此操作。
  • a) 你有你的控制器,你持有$scope - 你可以用它来格式化数据。 b) socket.io 不会改变任何东西。 c)如果我这样做,我可能会在将数据发送到客户端之前将数据更改回服务器中
  • U 我已经尝试了您的建议,但最终不得不恢复将times 与实际预订脱钩。虽然上面没有提到,但有多个房间可供预订。最终发生的情况是,如果房间从房间 A 切换到房间 B,那么房间 B 也会显示房间 A 的所有“保留”位置。我想这是因为 $scope.times 在所有房间之间共享。解决方法是每次更改房间时重置 $scope.times 数据,但如果可以使用指令处理这种条件格式,这似乎很多。
  • 所以你应该把times 放在room 里面(例如room.times.reservation)——从业务逻辑方面来说,这也有更多好处——如果你想让不同的房间有不同的时间未来
  • 这是个好主意!它确实提出了一些其他问题,但我相信这超出了这个特定 SO 主题的范围。我会接受你的正确答案,但你愿意和我聊几分钟关于设计的事情吗?我觉得您知道自己在做什么,并且可以直接回答我的后续问题。
【解决方案2】:

您可以使用$indexng-repeat 来使用reservation 数组中的相应对象。

并且,使用ng-show/ng-hide 显示/隐藏$scope.reservations.timeSlot == {{time.time}} 与否,以及类似的结果。

<table class="table table-hover">
    <thead>
    <tr>
        <th>Time</th>
        <th>Status</th>
        <th>Contact Person</th>
    </tr>
    </thead>
     <tbody>
      <tr ng-repeat="time in times" style="cursor:pointer">
        <td> {{time.time}}
       </td>
          <td>
              <div ng-show="reservations[$index].timeSlot == time.time">Already Taken</div>
              <button type="button" class="btn btn-info btn-lg" ng-click="open(time.time)" ng-hide="reservations[$index].timeSlot == time.time">Open</button>

          </td>
          <td>
               <div ng-show="reservations[$index].timeSlot == time.time">{{reservation[$index].netID}}</div>
               <div ng-hide="reservations[$index].timeSlot == time.time">---</div> 
          </td>
      </tr>
    </tbody>
  </table>

【讨论】:

  • 我喜欢这个解决方案,但它似乎没有完全遍历对象的 $scope.reservations 数组。它确实适用于第一个时间段,但在不同时间进行的任何其他预订都会更新。我需要在任何地方放置一个 ng-repeat 来让每个“时间”查看所有 $scope.reservations 对象并检查它们的 .timeSlot 吗?
  • reservation[$index] 正在通过预留数组。所以它应该可以解决问题。
  • 这似乎不会遍历reservations 数组中的每个reservation 对象。在每一行上循环的任何机制都需要类似于angular.forEach(reservations),并将1 timereservations 数组中的所有reservation.timeSlot 进行比较。我做了一个 Plunker,如果这有助于演示的话。 link to Plunker