每列 2 列的挖空

knockout foreach 2 columns

本文关键字:每列      更新时间:2023-09-26

我在尝试将数据格式化为 2 列时遇到了一些困难。

数据

self.safeFloatDenominations = [
        { denomination: "£50", value: 350 },
        { denomination: "£20", value: 780 },
        { denomination: "£10", value: 370 },
        { denomination: "£5", value: 280 },
        { denomination: "£2", value: 398 },
        { denomination: "£1", value: 491 },
        { denomination: "50p", value: 57.5 },
        { denomination: "20p", value: 62.8 },
        { denomination: "10p", value: 576.20 },
        { denomination: "5p", value: 85.05 },
        { denomination: "2p", value: 100.04 },
        { denomination: "1p", value: 35.12 },
    ];

法典

<div data-bind="foreach: safeFloatDenominations">
<input type="text" data-bind="value: value" />
<label data-bind="text: denomination"></label>
</div>

我想得到什么:

<div >
<input type="text" value="£50" />
<label>£50</label>
<input type="text" value="50p" />
<label>50p</label>
</div>
<div >
<input type="text" value="£20" />
<label>£50</label>
<input type="text" value="20p" />
<label>50p</label>
</div>
<div >
<input type="text" value="£10" />
<label>£50</label>
<input type="text" value="10p" />
<label>50p</label>
</div>
.......

有谁知道我如何拆分foreach,以便数据根据需要提供?

编辑

澄清一下,有谁知道如何拆分列表,以便列表数据的前半部分显示在第 1 列中,列表的后半部分显示在第 2 列中?

我同意 Matt 的回答,并考虑一种不同的元素布局方式。

话虽如此,你想要的是可行的。 在数组前面放一个computed,用于配对要在每列中显示的数据:

var vm = function() {
  var self = this;
  
  self.safeFloatDenominations = [
        { denomination: "£50", value: 350 },
        { denomination: "£20", value: 780 },
        { denomination: "£10", value: 370 },
        { denomination: "£5", value: 280 },
        { denomination: "£2", value: 398 },
        { denomination: "£1", value: 491 },
        { denomination: "50p", value: 57.5 },
        { denomination: "20p", value: 62.8 },
        { denomination: "10p", value: 576.20 },
        { denomination: "5p", value: 85.05 },
        { denomination: "2p", value: 100.04 },
        { denomination: "1p", value: 35.12 },
    ];
  
  self.denominationPairs = ko.computed(function() {
    var ret = [];
    for (var x = 0; x < self.safeFloatDenominations.length; x+=2) {
      var pair = {};
      pair['left'] = self.safeFloatDenominations[x];
      if (x+1 < self.safeFloatDenominations.length)
        pair['right'] = self.safeFloatDenominations[x+1]
        ret.push(pair);
    }
    return ret;
  });
};
ko.applyBindings(new vm());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="foreach: denominationPairs ">
  <div>
    <input type="text" data-bind="value: left.value" />
    <label data-bind="text: left.denomination"></label>
    <!-- ko if: right != null -->
      <input type="text" data-bind="value: right.value" />
      <label data-bind="text: right.denomination"></label>
    <!-- /ko -->
  </div>
</div>

但实际上,请尝试使用不同的布局!

您是否考虑过使用引导程序之类的东西?您可以在外div放置一类col-sm-6,这会将行放在 2 列中。此方法是首选方法,因为只需添加 col-md-4 这样的类即可轻松构建响应式布局,这将在中型屏幕上并排放置 3 列。同样,col-xs-12只会在手机上创建 1 列。

下面是 JSFiddle 上的一个示例。

编辑:

好的,我现在明白了,列需要是中间记录旁边的第一条记录,上面的方法会将第一条记录放在第二条记录旁边。

要实现此行为,使用敲除重复可能是最简单的方法。

将数据拆分为 2 个数组,前半部分和后半部分。(这些可以计算(

var half = self.safeFloatDenominations.length / 2;
self.sfd_part1 = self.safeFloatDenominations.slice(0, half);
self.sfd_part2 = self.safeFloatDenominations.slice(half);

然后在 HTML 中

<div data-bind="repeat: { count: sfd_part1.length }">
    <input type="text" data-bind="value: sfd_part1[$index].value" />
    <label data-bind="text: sfd_part1[$index].denomination"></label>
    <input type="text" data-bind="value: sfd_part2[$index].value" />
    <label data-bind="text: sfd_part2[$index].denomination"></label>
</div>

这是一个JSFiddle。