2016-12-06 59 views
2

我使用引导程序传送带在每个传送带项目中显示两列数据。这是我在做什么一个简单的例子:将数据拆分为两个带敲除的引导列

<div class="carousel-inner col-sm-12" role="listbox" data-bind="foreach: { data: dataSlides, as: 'slide' }"> 
    <div class="item" data-bind="css: { active: $index() == 0 }"> 
     <div class="col-sm-6" data-bind="foreach: { data: dataLeft, as: 'data' }"> 
      <div data-bind="text: data"></div> 
     </div> 
     <div class="col-sm-6" data-bind="foreach: { data: dataRight, as: 'data' }"> 
      <div data-bind="text: data"></div> 
     </div> 
    </div> 
</div> 

和数据模型我有,使用这样的结构:

self.dataSlides = ko.observableArray(
[ 
    { dataLeft: ['data 1', 'data 2', 'data 3'], dataRight: ['data 4', 'data 5', 'data 6'] }, 
    { dataLeft: ['data 7', 'data 8', 'data 9'], dataRight: ['data 10', 'data 11', 'data 12'] } 
]); 

这工作正常但有一个问题。在我的实际实现中,显示我的数据<div data-bind="text: data"></div>的部分非常复杂,正如您所看到的,我必须将其写入2次。一次用于我的左侧数据,一次用于我的正确数据。

我想要做的是将我的数据放入一个数据数组(无dataLeft/dataRight),并在左列中显示一半数据,在右列显示另一半数据。这样我就不必写数据显示循环两次。

要做到这一点,我需要以某种方式关闭并重新打开列标记,当foreach通过一半的数据。我尝试了以下操作,但这不起作用,因为它打破了以下的习俗:

<!-- ko if: $index() == data().length/2 --> 
</div> 
<div class="col-sm-6"> 
<!-- /ko --> 

我该怎么做?

+0

也'数据()。因为长度应该是长度,所以“长度/ 2”不起作用。 – gkb

回答

1

我认为修改您的数据以简化视图和数据绑定并不是一个坏主意。你不应该手动做。

一个好方法,这些类型的问题是两个变量的工作:

  1. 的(可观察)数据:你的情况,幻灯片
  2. 一个或多个数据数组“表示法“:自动(computed)版本的数据,可对其进行过滤,分类或重构以匹配您的查看目的。

因此,对于你的情况,我想提出一个ko.pureComputed变量:

  1. 手表原始数据源,并自动计算,
  2. x行,每列y每个z幻灯片。

实现示例(不是“最聪明”的方式做到这一点,我试图使它易于阅读...不要介意造型):

var dataSlides = ko.observableArray(["slide 1","slide 2","slide 3","slide 4","slide 5","slide 6","slide 7","slide 8","slide 9","slide 10","slide 11","slide 12"]); 
 

 
var dataTable = ko.pureComputed(function() { 
 
    var rows = []; 
 
    var slidesPerCol = 3; 
 
    var colPerRow = 2; 
 
    var slidesPerRow = slidesPerCol * colPerRow; 
 
    
 
    dataSlides().forEach(function(slide, index) { 
 
    var rowNr = Math.floor(index/slidesPerRow); 
 
    var colNr = Math.floor((index % slidesPerRow)/slidesPerCol); 
 
    
 
    rows[rowNr] = rows[rowNr] || getRow(colPerRow); 
 
    rows[rowNr][colNr].push(slide); 
 
    }); 
 
    
 
    return rows; 
 
}); 
 

 
ko.applyBindings({ 
 
    dataTable: dataTable, 
 
    pushSlide: function(){ 
 
    dataSlides.push("slide " + dataSlides().length); 
 
    } 
 
}); 
 

 
// Util 
 
function getRow(c, s) { 
 
    return Array(c) 
 
    .fill(null) 
 
    .map(function() { return []; }); 
 
}
.table { 
 
    border: 1px solid black; 
 
} 
 

 
.row { 
 
    display: flex; 
 
    justify-content: space-between; 
 
} 
 

 
.row:nth-child(odd) { 
 
    background: rgba(0,0,0,0.1); 
 
} 
 

 
.col { 
 
    flex: 1; 
 
    display: flex; 
 
    flex-direction: column; 
 
    justify-content: stretch; 
 
} 
 

 
.col + .col { border-left: 1px solid black; } 
 

 
.slide { 
 
    flex: 1; 
 
    text-align: center; 
 
    padding: .5rem; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div data-bind="foreach: { data: dataTable, as: 'row' }" class="table"> 
 
    <div data-bind="foreach: { data: row, as: 'col' }" class="row"> 
 
    <div data-bind="foreach: { data: col, as: 'slide'}" class="col"> 
 
     <span data-bind="text: slide" class="slide"></span> 
 
    </div> 
 
    </div> 
 
</div> 
 
<button data-bind="click: pushSlide">add slide</button>

+0

我的数据垂直显示不是水平的,'数据1/2/3'低于彼此。每个轮播项目包含2列,数据旋转90°到您的解决方案。 –

+0

这是更多的CSS变化我猜...我已经改变了'flex-direction'到'column'应该是正确的。尽管如此,真正的答案是在'ko.pureComputed' – user3297291

+0

由于我不能使用flex,因为我必须支持较旧的IE版本,所以这不是一个真正的选择。 –

0

我认为你应该有一个容器左边的列和右边的列,每个列表中的每个列表的一半。

喜欢这个例子: https://jsfiddle.net/Salmin/2ytouxvs/2/

self.dataSlides = ko.observableArray(
    [ 
     ['data 1a', 'data 2a', 'data 3a', 'data 4a', 'data 5a', 'data 6a'], 
     ['data 1b', 'data 2b', 'data 3b', 'data 4b', 'data 5b', 'data 6b'] 
    ]); 


<div class="carousel-inner col-sm-12" role="listbox" data-bind="foreach: dataSlides, as: 'slide'"> 

    <div class="item-2"> 
    <div class="col-sm-6" data-bind="foreach: $data"> 
    <!-- ko if: $index()+1 < $data.length/2 --> 
     <div data-bind="text: $data"></div> 
    <!-- /ko --> 
    </div> 
    </div> 

    <div class="item-2"> 
    <div class="col-sm-6" data-bind="foreach: $data"> 
    <!-- ko if: $index()+1 > $data.length/2 --> 
     <div data-bind="text: $data"></div> 
    <!-- /ko --> 
    </div> 
    </div> 

</div> 
+0

谢谢你的答复。这并不能解决我的问题,即我必须将显示部分'

'写入2次。在我的实现中,这是相当多的代码,我想只有一次。 –