基本上我正在尝试通过Knockout和JSON对象填充Bootstrap模板。
<div class="row-fluid">
<div class="span4">
<h1>App Title</h1>
<p>App Description</p>
</div>
<div class="span4">
<h1>App Title</h1>
<p>App Description</p>
</div>
<div class="span4">
<h1>App Title</h1>
<p>App Description</p>
</div>
</div>
<div class="row-fluid">
<div class="span4">
<h1>App Title</h1>
<p>App Description</p>
</div>
<div class="span4">
<h1>App Title</h1>
<p>App Description</p>
</div>
<div class="span4">
<h1>App Title</h1>
<p>App Description</p>
</div>
</div>
...
var viewModel;
$.get('AppData.json', function (data) {
jsonData = $.parseJSON(data);
viewModel = ko.mapping.fromJS(jsonData);
var apps = viewModel.Apps();
ko.applyBindings(viewModel);
});
问题是我无法让Knockout在索引模3的条件下运行淘汰后注入</div><div class="row-fluid">
...我假设因为那些<div>
标签悬空/未关闭。
简而言之,如何让viewModel.Apps();
的对象数组适合上述Bootstrap脚手架?
答案 0 :(得分:10)
创建一个计算的observable,将apps
可观察/可观察数组切成三个元素的数组,然后用foreach
绑定将一些根元素绑定到它。这样的事情。
可观察:
viewModel.appRows = ko.computed(function() {
var apps = this.Apps();
var result = [];
for (var i = 0; i < apps.length; i += 3) {
var row = [];
for (var j = 0; j < 3; ++j) {
if (apps[i + j]) {
row.push(apps[i + j]);
}
}
result.push(row);
}
return result;
}, viewModel);
标记:
<div class="container" data-bind="foreach: appRows">
<div class="row-fluid" data-bind="foreach: $data">
<div class="span4">
<h1 data-bind="text: title"></h1>
<p data-bind="text: description"></p>
</div>
</div>
</div>
答案 1 :(得分:7)
我必须自己解决一个非常类似的问题:使用可观察的数组渲染bootstrap网格但使用bootstrap v3和ko v3.0。我将把解决方案留在这里以供将来参考。
我使用的是普通函数而不是计算函数,因为默认情况下使用它们实现绑定(请参阅此处的RP Niemeyer答案https://stackoverflow.com/a/6712389/323751)
在我的视图模型中:
this.partitioned = function (observableArray, count) {
var rows, partIdx, i, j, arr;
arr = observableArray();
rows = [];
for (i = 0, partIdx = 0; i < arr.length; i += count, partIdx += 1) {
rows[partIdx] = [];
for (j = 0; j < count; j += 1) {
if (i + j >= arr.length) {
break;
}
rows[partIdx].push(arr[i + j]);
}
}
return rows;
};
模板:
<div data-bind="foreach: partitioned(userProjects, 3)">
<div class="row"
data-bind="template: { name: 'projectCell', foreach: $data }"></div>
</div>
<script id="projectCell" type="text/html">
<div class="col-md-4" data-bind="text: name"></div>
</script>
希望有人觉得这很有用。
答案 2 :(得分:1)
我正在使用bootstrap3并希望每行有x个对象,其中x取决于窗口大小,例如col类。
例如我有类的元素:
col-lg-2 col-md-2 col-sm-3 col-xs-4
所以
如果是xs那么一行有3个项目
如果lg那么一行有6个项......
我扩展了rkhayrov的答案以使其发挥作用
/* determine the current bootstrap environment */
function findBootstrapEnvironment() {
var envs = ['xs', 'sm', 'md', 'lg'];
$el = $('<div>');
$el.appendTo($('body'));
for (var i = envs.length - 1; i >= 0; i--) {
var env = envs[i];
$el.addClass('hidden-'+env);
if ($el.is(':hidden')) {
$el.remove();
return env
}
};
}
/* determine How many objs per row */
function determineObjectsPerRow(){
switch(findBootstrapEnvironment()) {
case 'xs':
return 3;
break;
case 'sm':
return 4;
break;
case 'md':
return 6;
break;
case 'lg':
return 6;
break;
}
}
var objsPerRow= determineObjectsPerRow();
for (var i = 0; i < apps.length; i += objsPerRow) {
var row = [];
for (var j = 0; j < objsPerRow; ++j) {
if (apps[i + j]) {
row.push(apps[i + j]);
}
}
result.push(row);
}
我在宽度和高度上添加了一个依赖项,它们是可观察的 因此,如果调整窗口大小,将重新计算函数
var base = {
AppModel:function (data) {
var self = this;
self.data = ko.observable({
documents:ko.observableArray([]),
width:ko.observable($(window).width()),
height:ko.observable($(window).height())
});
/* calculate rows based on bootstrap environment */
self.appRows = ko.computed(function() {
self.data().height();
self.data().width();
var apps = self.data().documents();
var result = [];
var objsPerRow= determineObjectsPerRow();
for (var i = 0; i < apps.length; i += objsPerRow) {
var row = [];
for (var j = 0; j < objsPerRow; ++j) {
if (apps[i + j]) {
row.push(apps[i + j]);
}
}
result.push(row);
}
return result;
}, self);
},
};
和调整大小处理程序
$(window).resize(function(event) {
vm.data().height($(window).height());
vm.data().width($(window).width());
});
它就像Charme一样,为每个设备宽度生成很好的行
如果有人需要达到相同的目的,我会把它留在这里