javascript 限制 foreach 循环淘汰赛
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17840753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Limit foreach loop knockout
提问by EntryLevel
I have this knockout mapping my array retreived from the ajax call below.
我有这个淘汰赛映射我从下面的 ajax 调用中检索到的数组。
function InvoiceViewModel(data) {
var self = this;
self.survey = data;
}
Ajax Call
Ajax 调用
$.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');
}
});
My Array
我的数组
var test = {
Name: Blah,
Attributes: [
{Name: Test, Type: Photo, Year:1988},
{Name: Test, Type: Photo, Year:1988},
{Name: Test, Type: Photo, Year:1988}
]
};
How I am binding my data
我如何绑定我的数据
<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>
I need a way to limit my attributes foreach loop to only show 2 of the 3 attributes. I have only found a few things on how to do this and they seem very overly complicated. I cannot imagine there is not a simple way to do this in knockout.
我需要一种方法来将我的属性 foreach 循环限制为仅显示 3 个属性中的 2 个。我只发现了一些关于如何做到这一点的事情,而且它们看起来非常复杂。我无法想象在淘汰赛中没有一种简单的方法可以做到这一点。
回答by Patrick M
If you always have 3 attributes and you always only want to show 2 of them, you don't need to foreach them, exactly.
如果您总是有 3 个属性,而您总是只想显示其中的 2 个,那么您不需要完全使用 foreach。
However, there is the special binding context variable $index()
, which will let you do some basic hiding, although it wouldn't prevent rendering. Because $index is 0-based, the condition is $index() < 2
. As Andrey points out in the comments, $index
is an observable, so you have to call it with parentheses as a method, or comparisons won't do what you expect (you'll be comparing an int against a function).
然而,有一个特殊的绑定上下文变量$index()
,它可以让你做一些基本的隐藏,虽然它不会阻止渲染。因为 $index 是从 0 开始的,所以条件是$index() < 2
。正如安德烈在评论中指出的,$index
是一个 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>
If you want a generic limiter on a foreach loop, you're right, it's not simple. You would have to make a custom binding.
如果您想在 foreach 循环上使用通用限制器,您是对的,这并不简单。您将不得不进行自定义绑定。
Another approach you could consider is pre-processing your data in the viewmodel. When you set this.survey = data;
, you could remove any of the attributes you don't want to display at that point.
您可以考虑的另一种方法是在视图模型中预处理您的数据。设置 时this.survey = data;
,您可以删除此时不想显示的任何属性。
Edit: I see from your edit that you know about the ko: if
psuedo-elements. I completely forgot about those, but you could easily use one to prevent rendering template items beyond a certain index. The foreach
would still evaluate the observable, that should not have any kind of huge overhead by itself.
编辑:我从您的编辑中看到您了解ko: if
伪元素。我完全忘记了这些,但是您可以轻松地使用一个来防止呈现超出某个索引的模板项目。该foreach
会还评估观察到的,不应该由它本身有什么样的巨大开销。
回答by Michael Best
JavaScript arrays include the excellent slice
method that should fill your need nicely:
JavaScript 数组包含一个很好的slice
方法,可以很好地满足您的需求:
template: { name: 'photo-template', foreach: Attributes.slice(0,2) }
But as @Patrick-M mentioned, you don't need a loop:
但正如@Patrick-M 提到的,你不需要循环:
template: { name: 'photo-template', data: Attributes[0] }
template: { name: 'photo-template', data: Attributes[1] }
My Repeatbinding includes an option for limiting the number of repetitions:
我的重复绑定包括一个限制重复次数的选项:
<div data-bind="repeat: { foreach: Attributes, count: 2 }"
data-repeat-bind="template: { name: 'photo-template', data: $item() }">
</div>
回答by Guest
You can create computed with limited array limit:
您可以使用有限的数组限制创建计算:
var limited = ko.computed( function() {
return Attributes.slice(0, limit);
});
Then all you have to do to foreach limited. You can even add somekind of "more" element:
然后你所要做的就是 foreach 受限。您甚至可以添加某种“更多”元素:
<!-- ko if: Attributes().length > limit -->
<div class="more">...</div>
<!--/ko-->
I hope it will be helpful for further generations ;)
我希望它能对后代有所帮助;)
回答by Joel Davey
The simplest way in a foreach is to use the $index
foreach 中最简单的方法是使用 $index
<!-- ko foreach: { data: Attributes, as: 'item' } -->
<!-- ko if: $index() < 2 -->
<span class="item" data-bind="text:item.name"></span>
<!-- /ko -->
<!-- /ko -->
回答by Phani Kumar
Can try as below:
可以尝试如下:
<!-- ko foreach: { data: attributes, as: 'item' } -->
<!-- ko if: $index() < 2 -->
<span class="item" data-bind="text:item.name"></span>
<!-- /ko -->
<!-- /ko -->
Example :
例子 :
<ul data-bind="foreach: listItems">
<li data-bind="attr: {id: id} ">
<a href="#" data-bind="text: label"></a>
</li>
</ul>
回答by Gilberto B. Terra Jr.
Put the .slice(0,1) to get first 2 items from your FOREACH data-bind array (model).
放入 .slice(0,1) 以从 FOREACH 数据绑定数组(模型)中获取前 2 个项目。
.slice(0,1)
Something like this
像这样的东西
<!-- ko foreach: { data: items().slice(0, 1) } -->
<div>
Your html here!
</div>
<!-- /ko -->
Or if you prefer
或者如果你喜欢
<tbody data-bind="foreach: people.slice(0, 1)">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
</tr>
</tbody>
About slice() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice
关于 slice() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice
回答by Jake Moon
I solved a similar problem by pushing a subset of the original array items to another array in my viewmodel, then binding to the subset array.
我通过将原始数组项的子集推送到我的视图模型中的另一个数组,然后绑定到子集数组来解决类似的问题。
回答by Rick Klaassen
you can limit a loop in this way:
您可以通过这种方式限制循环:
for(var i=0;i<data.length;i++){
if(i>1){
return false;
}
}