使用 Knockoutjs 创建网格
Create grid with knockoutjs
假设我们有一个可观察的 N+1 个元素数组。我想实现的是使用这些元素的按钮构建 3 x X 网格。比如手机键盘或类似的东西。
到目前为止,我所做的是创建一个带有foreach和if的表:
<table>
<tbody data-bind="foreach: tableList">
<!-- ko if: isEof($index()) -->
<tr>
<!-- /ko -->
<td><button data-bind="text: name"></button></td>
<!-- ko if: isEof($index()) -->
</tr>
<!-- /ko -->
</tbody>
</table>
isEof() 函数应该通过列表索引来确定我们已经渲染了 3 个元素。如果是,那么它将呈现标签。此外,如果索引为 0,则它也呈现元素。这是函数的代码:
function TableItem(data){
this.id=ko.observable(data.id);
this.name=ko.observable(data.name);
this.isEof = function(index){
if(index ==0){
return true;
}else{
if((index+3) % 3 === 0){
return true;
}else{
return false;
}
}
}
}
但是我在此设置中面临两个问题。
1) 启用这些如果块,按钮名称绑定不起作用。当我删除 ko if 块时,它将正确呈现。
2) KO if 语句似乎无法正常工作。它将仅渲染那些行,其中也允许渲染。
我已经制作了我的解决方案的 JSFiddle 示例:http://jsfiddle.net/kpihus/3Lw7xjae/2/
我会创建一个ko.computed
,将表项目列表转换为数组数组:
var TableItem = function TableItem(data) {
this.id = ko.observable(data.id);
this.name = ko.observable(data.name);
};
var Vm = function Vm() {
this.tableItems = ko.observableArray([]);
this.columnCount = ko.observable(3);
this.columns = ko.computed(function() {
var columns = [],
itemCount = this.tableItems().length,
begin = 0;
// we use begin + 1 to compare to length, because slice
// uses zero-based index parameters
while (begin + 1 < itemCount) {
columns.push( this.tableItems.slice(begin, begin + this.columnCount()) );
begin += this.columnCount();
}
return columns;
// don't forget to set `this` inside the computed to our Vm
}, this);
};
vm = new Vm();
ko.applyBindings(vm);
for (var i = 1; i < 15; i++) {
vm.tableItems.push(new TableItem({
id: i,
name: "name: " + i
}));
}
这样,您可以通过嵌套两个foreach
绑定来显示表:
<table>
<tbody data-bind="foreach: { data: columns, as: 'column' }">
<tr data-bind="foreach: column">
<td>
<button data-bind="text: name">A</button>
</td>
</tr>
</tbody>
</table>
JSFiddle
如果你以前没有使用过ko.computed
,他们会跟踪它们内部访问的任何可观察量——在本例中是this.tableItems
和this.columnCount
——每当其中一个发生变化时,它们就会再次运行并产生新的结果。
this.columns
采用我们的表项数组
[TableItem, TableItem, TableItem, TableItem, TableItem, TableItem]
并按this.columnCount
将它们分组为
[[TableItem, TableItem, TableItem], [TableItem, TableItem, TableItem]]
我们可以通过简单地传递$root
来实现这一点,这将具有tableList
并以简单的方式进行循环。
查看模型:
function TableItem(data) {
var self = this;
self.id = ko.observable(data.id);
self.name = ko.observable(data.name);
self.pickarray = ko.observableArray();
self.isEof = function (index, root) {
if (index === 0) {
self.pickarray(root.tableList().slice(index, index + 3));
return true;
} else if ((index + 3) % 3 === 0) {
self.pickarray(root.tableList().slice(index, index + 3));
return true;
} else {
return false;
}
}
}
var vm = function () {
this.tableList = ko.observableArray();
for (var i = 1; i < 15; i++) {
this.tableList.push(new TableItem({
id: i,
name: "name: " + i
}));
}
}
ko.applyBindings(new vm());
视图:
<table data-bind="foreach:tableList">
<tr data-bind="if:isEof($index(),$root)">
<!-- ko foreach: pickarray -->
<td>
<button data-bind="text: id"></button>
</td>
<!-- /ko -->
</tr>
</table>
这里的技巧非常简单,我们只需要有条件地填充pickarray
就可以为我们完成工作。
在这里工作小提琴
相关文章:
- 使用导航属性创建Kendo UI网格模型的问题
- 如何在创建新网格之前销毁网格堆栈
- 如何在ExtJS网格上创建带有标签的文本字段
- 如何使用角度两个绑定来动态创建的剑道网格
- Kinetic.js–创建网格
- 创建过去365天的日历网格
- Three.js:我可以创建网格来替换很多对象吗
- 如何在Meteor.js中使用车把创建网格系统
- 如何在Jquery中使用kendo ui创建内联网格编辑
- 如何为剑道网格创建、更新和删除IList中的数据
- Masonry:在AJAX回调上创建一个网格
- JavaScript-从脚本中的单词列表创建一个html表或网格
- 如何使用javascript在选中网格视图复选框时创建表行
- 角度.js ng 重复用于创建网格
- C#网格视图从动态创建的DataTable中实现可点击单元格
- 我怎么能用Codeigniter在可滚动的部分创建一个无限向下滚动的网格加载程序呢
- 在网格内创建一个在单击时打开的菜单
- 为全局网格创建 LatLng 对数组
- 剑道UI网格创建聚合函数
- 在Javascript / jQuery中基于选项网格创建递归函数