【发布时间】:2018-04-13 21:42:54
【问题描述】:
我有一个可观察的整数,pages,我想循环到 html 中页面的值,例如。
pages = ko.observable(3)
生产
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
是否有适合此的绑定?
【问题讨论】:
标签: knockout.js
我有一个可观察的整数,pages,我想循环到 html 中页面的值,例如。
pages = ko.observable(3)
生产
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
是否有适合此的绑定?
【问题讨论】:
标签: knockout.js
你可以这样写:
<ul data-bind="foreach: new Array(pages())">
<li data-bind='text: $index()+1'></li>
</ul>
这是工作小提琴:http://jsfiddle.net/L8Uy5/
【讨论】:
ko.computed。完全忘记了 $index 属性!
如果你只需要一个简单的for 循环,你可以这样做:
<select name="something"
data-bind="foreach: new Array(10)">
<option data-bind="text: $index()+1, value: $index()+1"></option>
</select>
您可以通过将(10) 替换为任意数字来指定项目数。
这将生成一个简单的下拉列表,其中包含从 1 到 10 的数字。
【讨论】:
The answer by Artem Vyshniakov 是一种在视图中运行而不更改视图模型的快速方法。但是,如果您希望快速扩展设置,或者只是不喜欢在您看来拥有(可以说是可单元测试的逻辑)new Array(pages()),这里有一个替代解决方案。另一个好处可能是您还可以封装$index + 1 位:
function ViewModel() {
var self = this;
self.pages = ko.observable(3);
self.pageArray = ko.computed(function() {
var list = [];
var length = parseInt(self.pages(), 10); // the <input> makes `pages` a string!
for (var i = 1; i <= length; i++) {
list.push(i);
}
return list;
});
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="textInput: pages" type="number">
<ul data-bind="foreach: pageArray">
<li data-bind="text: $data"></li>
</ul>
pageArray 代码主要是庞大的,因为 (a) pages 由于输入而变成字符串,这可能通过将 pages 变为可写计算来更好地解决,以及 (b) 因为我选择使用用于创建范围的for 循环/基本 解决方案(在此基础上you could improve)。
这是一个在两个方面都有改进的建议版本:
function ViewModel() {
var self = this,
_pages = ko.observable(3);
self.pages = ko.computed({
read: () => _pages(),
write: newVal => _pages(parseInt(newVal, 10))
});
self.pageArray = ko.computed(() => _.range(1, _pages() + 1));
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="textInput: pages" type="number">
<ul data-bind="foreach: pageArray">
<li data-bind="text: $data"></li>
</ul>
无论如何,pageArray 及其内容现在完全可以进行单元测试,并且可供其他视图模型逻辑位访问。 (如果你不需要那个,例如你只是在搭建一个视图,我会说选择另一个答案)。
【讨论】:
它不适用于更新字段
你可以这样写:
这是工作小提琴:http://jsfiddle.net/L8Uy5/
这个效果更好https://jsfiddle.net/L8Uy5/54/
function ViewModel(){
var self = this;
self.pages = ko.observable(3);
self.virtual_elements = ko.computed(function(){
var arr = [];
for (var i=1; i<=self.pages(); i++) {
arr.push('some');
}
return arr;
});
}
ko.applyBindings(new ViewModel());
<input data-bind="value: pages"/>
<ul data-bind="foreach: virtual_elements">
<li data-bind='text: $index()+1'></li>
</ul>
【讨论】:
input 时,它比从这个答案中对 pages 变为 字符串 的替代方案更不宽容。我确实喜欢computed 的想法,但for other reasons。