限制foreach循环淘汰赛

时间:2013-07-24 17:18:39

标签: javascript html knockout.js

我有这个淘汰映射我的数组从下面的ajax调用中恢复过来。

function InvoiceViewModel(data) {
var self = this;

self.survey = data;

}

Ajax Call

$.ajax({
    url: 'http://localhost:43043/api/damage',
    type: 'GET',
    headers: { 'Accept': 'application/json' },
    data: {
        orderNumber: num,
        category: cat
    },
    success:
           function (data) {
               var usingRoutData = document.URL;
               ko.applyBindings(new InvoiceViewModel(data));
           },

    error: function () {
        alert('failure');
    }

});

我的数组

 var test = {
  Name: Blah,
  Attributes: [
               {Name: Test, Type: Photo, Year:1988},
               {Name: Test, Type: Photo, Year:1988},
               {Name: Test, Type: Photo, Year:1988}
              ]
            };

我如何绑定我的数据

 <div id="invoiceBodyWrapper">
<div data-bind="template: { name: 'invoice-template', foreach: surveys }">
</div>

<div class="invoiceWrapper">
    </div>
    <div id="completePictureWrapper" data-bind="template: { name: 'photo-template',     foreach: new Array(Attributes) }"></div>

</div>
</script>

<script type="text/html" id="photo-template">
<!-- ko if: classification === 'photo' -->
<div id="pictureWrappers">
    <img class="img" data-bind="attr: { src: 'http://myimagepath/download/full/' +    $index()+1 }" />
</div>
<!-- /ko -->
 </script>
  <script src="~/Scripts/DamageInvoiceCreation.js"></script>

我需要一种方法来限制foreach循环的属性,只显示3个属性中的2个。我只发现了一些关于如何做到这一点的事情,它们看起来非常复杂。我无法想象在淘汰赛中没有一种简单的方法可以做到这一点。

8 个答案:

答案 0 :(得分:7)

如果你总是有3个属性,并且你总是只想显示其中的两个,那么你就不需要完全预知它们。

但是,有一个特殊的绑定上下文变量$index(),它可以让你做一些基本的隐藏,虽然它不会阻止渲染。因为$ index是从0开始的,所以条件是$index() < 2。正如安德烈在评论$index is an observable中指出的那样,所以你必须用括号作为方法来调用它,否则比较将不会达到预期的效果(你将把int与函数进行比较)。

<ul data-bind="foreach: survey.Attributes">
    <li data-bind="visible: $index() < 2">
        Name: <span data-bind="text: Name"> </span><br/>
        Type: <span data-bind="text: Type"> </span><br/>
        Year: <span data-bind="text: Year"> </span><br/>
    </li>
</ul>

如果你想在foreach循环上使用通用限制器,那么你是对的,这并不简单。您必须制作custom binding

您可以考虑的另一种方法是在viewmodel中预处理数据。设置this.survey = data;时,您可以删除此时不想显示的任何属性。

编辑:我从您的编辑中看到您了解ko: if伪元素。我完全忘记了这些,但您可以轻松地使用一个来防止渲染模板项超出某个索引。 foreach仍将评估可观察量,它本身不应该有任何巨大的开销。

答案 1 :(得分:6)

JavaScript数组包含优秀的slice方法,可以很好地满足您的需求:

template: { name: 'photo-template', foreach: Attributes.slice(0,2) }

但正如@ Patrick-M所提到的,你不需要循环:

template: { name: 'photo-template', data: Attributes[0] }
template: { name: 'photo-template', data: Attributes[1] }

我的Repeat绑定包含一个限制重复次数的选项:

<div data-bind="repeat: { foreach: Attributes, count: 2 }"
      data-repeat-bind="template: { name: 'photo-template', data: $item() }">
</div>

答案 2 :(得分:3)

您可以使用有限的数组限制创建计算:

var limited = ko.computed( function() {
   return Attributes.slice(0, limit);
});

然后你需要做的就是限制。你甚至可以添加一些“更多”元素:

<!-- ko if: Attributes().length > limit -->
    <div class="more">...</div>          
<!--/ko-->

我希望它对后代有所帮助;)

答案 3 :(得分:0)

你可以用这种方式限制循环:

for(var i=0;i<data.length;i++){
   if(i>1){
      return false;
   }
}

答案 4 :(得分:0)

我通过将原始数组项的子集推送到viewmodel中的另一个数组,然后绑定到子集数组来解决类似的问题。

答案 5 :(得分:0)

foreach中最简单的方法是使用$ index

<!-- ko foreach: { data: Attributes, as: 'item' } -->
<!-- ko if: $index() < 2 -->
<span class="item" data-bind="text:item.name"></span>
<!-- /ko -->
<!-- /ko -->

答案 6 :(得分:0)

可以尝试以下操作:

 <!-- ko foreach: { data: attributes, as: 'item' } -->
    <!-- ko if: $index() < 2 -->
    <span class="item" data-bind="text:item.name"></span>
    <!-- /ko -->
    <!-- /ko -->

示例:

<ul data-bind="foreach: listItems">
                <li data-bind="attr: {id: id} ">
                  <a href="#" data-bind="text: label"></a>
                </li>
 </ul>

答案 7 :(得分:0)

放入.slice(0,1),以从FOREACH数据绑定数组(模型)中获取前2个项目。

.slice(0,1)   

类似这样的东西

<!-- ko foreach: { data: items().slice(0, 1) } -->
    <div>
        Your html here!
    </div>
<!-- /ko -->

或者,如果您愿意

<tbody data-bind="foreach: people.slice(0, 1)">
    <tr>
        <td data-bind="text: firstName"></td>
        <td data-bind="text: lastName"></td>
    </tr>
</tbody>

关于slice() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice