J'ai un entier observable, pages
, et je veux boucler jusqu'à la valeur des pages dans le code HTML par exemple.
pages = ko.observable(3)
produit
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Existe-t-il une liaison qui convient à cela?
Vous pouvez écrire quelque chose comme ceci:
<ul data-bind="foreach: new Array(pages())">
<li data-bind='text: $index()+1'></li>
</ul>
Voici le violon en marche: http://jsfiddle.net/L8Uy5/
La réponse de Artem Vyshniakov est un excellent moyen rapide de faire fonctionner cette vue dans la vue sans changer le modèle de vue. Toutefois, si vous envisagez d'étendre rapidement la configuration, ou si vous n'aimez pas avoir (ce qui est sans doute une logique testable par unité) new Array(pages())
à votre avis, voici une solution alternative. Un avantage supplémentaire pourrait être que vous pouvez également encapsuler le bit $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>
Le code pageArray
est généralement volumineux car (a) pages
devient une chaîne à cause de l'entrée, qui pourrait être mieux résolue en transformant pages
en calculable inscriptible, et (b) parce que j'ai choisi d'utiliser un for
boucle/basic solution pour créer la gamme (sur laquelle vous pourriez améliorer ).
Voici une version suggérée qui améliore les deux points:
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>
Quoi qu'il en soit, pageArray
et son contenu sont maintenant entièrement testables par unité et accessibles à d'autres bits de la logique du modèle de vue. (Si vous n'en avez pas besoin, par exemple si vous n'échafaudez qu'une vue, je vous prierais d'aller avec l'autre réponse).
Si vous avez juste besoin d'une simple boucle for
, vous pouvez faire quelque chose comme ceci:
<select name="something"
data-bind="foreach: new Array(10)">
<option data-bind="text: $index()+1, value: $index()+1"></option>
</select>
Vous pouvez spécifier le nombre d'éléments en remplaçant (10)
par n'importe quel nombre ..__ Cela produira un simple menu déroulant contenant des nombres de 1 à 10.