尝试使用foreach有序列表并将列表项随机播放。我创建了一个函数( randomOrder )并在foreach项的绑定中使用它。 似乎没什么用。
HTML:
<ol data-bind="foreach: { data: docs, randomOrder: true} ">
<li class="result" data-bind="component: { name: 'physicianreferral.docresult', params: { doc: $data } }"></li>
</ol>
JS:
ko.bindingHandlers.randomOrder = {
init: function (elem, valueAccessor) {
// Build an array of child elements
var child = ko.virtualElements.firstChild(elem),
childElems = [];
while (child) {
childElems.push(child);
child = ko.virtualElements.nextSibling(child);
}
// Remove them all, then put them back in a random order
ko.virtualElements.emptyNode(elem);
while (childElems.length) {
var randomIndex = Math.floor(Math.random() * childElems.length),
chosenChild = childElems.splice(randomIndex, 1);
ko.virtualElements.prepend(elem, chosenChild[0]);
}
}
};
ko.virtualElements.allowedBindings.randomOrder = true;
答案 0 :(得分:2)
首先,您的绑定不属于foreach
,因此必须在顶级指定:
foreach: docs, randomOrder: true
但我建议你根本不使用这种方法。只需将传递给foreach
的数组随机化:
foreach: randomize(docs)
JS:
function randomize(arr) {
var newArray = [];
while (arr.length) {
var randomIndex = Math.floor(Math.random() * arr.length);
newArray.push(arr.splice(randomIndex, 1)[0]);
}
return newArray;
};
答案 1 :(得分:0)
一些问题:首先,您尝试在foreach绑定中使用自定义绑定。您可以在同一HTML元素中使用多个绑定,但它们应以逗号分隔。
<ol data-bind="foreach: { data: docs }, randomOrder: true">
自定义绑定'init'方法具有allBindingAccessor,它提供了一种访问视图模型属性的方法,这些属性在同一元素的其他绑定中使用。
var array = allBindingsAccessor().foreach.data();
使用可用的数组,您可以使用任何算法来重新排列它。我在片段中添加了Fisher-Yates(aka Knuth)Shuffle,直接从这个answer复制。点击“运行代码段”,每次都看到它被洗牌。
ko.bindingHandlers.randomOrder = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var array = allBindingsAccessor().foreach.data();
var currentIndex = array.length, temporaryValue, randomIndex;
// while there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
allBindingsAccessor().foreach.data(array);
}
};
var ViewModel = function() {
var self = this;
self.docs = ko.observableArray([1, 2, 3, 4, 5, 6, 7, 8 ,9, 10]);
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ol data-bind="foreach: { data: docs }, randomOrder: true">
<li data-bind="text: $data"></li>
</ol>