我正在使用 Knockout 的 forech 数据绑定(bind)来呈现模板。问题是对于使用 foreach 绑定(bind)生成的每三个元素,我想创建一个带有类行的新 div。本质上,我只想在一行中显示三个元素。对于第四项,不应创建新行。但是 foreach 数据绑定(bind)已应用于行 div 内的 div。我该如何实现?以下是代码。
HTML
<div class="row">
<!-- Item #1 -->
<div class="col-md-4 col-sm-6 col-xs-12" data-bind="foreach:items">
<div data-bind="attr: {id: ID}" class="item">
<!-- Use the below link to put HOT icon -->
<div class="item-icon"><span>HOT</span></div>
<!-- Item image -->
<div class="item-image">
<a href="single-item.html"><img data-bind="attr: {src: picture}" src="img/items/2.png" alt="" class="img-responsive"/></a>
</div>
<!-- Item details -->
<div class="item-details">
<!-- Name -->
<h5><a data-bind="text: itemname" href="single-item.html">HTC One V</a></h5>
<div class="clearfix"></div>
<!-- Para. Note more than 2 lines. -->
<!--p>Something about the product goes here. Not More than 2 lines.</p-->
<hr />
<!-- Price -->
<div data-bind="text: price" class="item-price pull-left">$360</div>
<!-- qty -->
<div data-bind="text: quantity" class="item-price text-center">$360</div>
<!-- Add to cart -->
<div class="pull-right"><a href="#" class="btn btn-danger btn-sm">Add to Cart</a></div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
Javascript:
function itemsKo()
{
var self=this;
self.query = ko.observable();
self.hide = ko.observable(false);
self.items = ko.observableArray();
self.subcat=function()
{
$.ajax({
url: "/items,
type: "get",
success: function(data){
ko.utils.arrayForEach(data, function(item) {
item.price = "Rs" + item.price;
self.items.push(item);
});
//console.log(JSON.stringify(window.vm.items()));
},
error:function(jqXHR, textStatus, errorThrown) {
alert("failure");
}
});
}
}
最佳答案
最简单的解决方案是找到一种将数组映射到行/列结构的方法。因此,一个行数组,其中每一行都是该行中的一个元素数组。
这是一个较早的答案,它显示了在 VM 中创建计算以将数组表示为一组行:Knockout.js - Dynamic columns but limit to a maximum of 5 for each row
另一种选择是创建一个自定义绑定(bind)来处理这个为您计算的管道。优点是你不需要用额外的代码来膨胀你的 View 模型并且它是可重用的。一个可能的实现可能是这样的:
ko.bindingHandlers.rows = {
init: function (element, valueAccessor, allBindings, data, context) {
var rows = ko.computed({
read: function() {
var index, length, row,
options = ko.unwrap(valueAccessor()),
items = ko.unwrap(options.items),
columns = ko.unwrap(options.columns)
result = [];
for (index = 0, length = items.length; index < length; index++) {
if (index % columns === 0) {
//push the previous row, except the first time
if (row) {
result.push(row);
}
//create an empty new row
row = [];
}
//add this item to the row
row.push(items[index]);
}
//push the final row
if (row) {
result.push(row);
}
//we know have an array of rows
return result;
},
disposeWhenNodeIsRemoved: element
});
//apply the real foreach binding with our rows computed
ko.applyBindingAccessorsToNode(element, { foreach: function() { return rows; } }, context);
//tell KO that we will handle binding the children
return { controlsDescendantBindings: true };
}
};
这是一个快速的操作:http://jsfiddle.net/rniemeyer/nh6d7/
它是一个计算的,所以列数和元素是可以观察到的,并且会导致它在发生变化时重新呈现。如果您经常更新原始元素,这可能是一个小问题。
关于javascript - knockout - 动态生成 Bootstrap 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23844464/