淘汰foreach 2列

时间:2015-03-20 12:06:09

标签: javascript knockout.js

我在尝试将数据格式化为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列?

2 个答案:

答案 0 :(得分:1)

您是否考虑过使用像bootstrap这样的东西?您可以在外部col-sm-6上放置一个div类,将行放在2列中。这种方法是首选,因为这样可以通过简单地添加类似col-md-4的类来轻松构建响应式布局,这样可以在中型屏幕上并排放置3列。同样,col-xs-12只会在手机上创建一列。

以下是JSFiddle的示例。

修改

好的,我现在看到,列必须是中间记录旁边的第一个记录,上面的方法会将第一个记录放在第二个记录旁边。

要实现此行为,最简单的方法是使用knockout-repeat

将数据拆分为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

答案 1 :(得分:1)

我同意马特的回答,并考虑一种不同的方式来布置元素。

话虽如此,你想要的是可行的。将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>

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