我想用类似淘汰赛foreach结构的东西来遍历一个对象的属性。 这是我想创建...
期望的结果
<table>
<tr>
<td>Name 1</td>
<td>8/5/2012</td>
</tr>
<tr>
<td>Name 2</td>
<td>2/8/2013</td>
</tr>
</table>
然而,我的模型看起来像这样...
JS
function DataModel(){
this.data = ko.observableArray([{
entityId: 1,
props: {
name: 'Name 1',
lastLogin: '8/5/2012'
}
},
{
entityId: 2,
props: {
name: 'Name 2',
lastLogin: '2/8/2013'
}
}]);
}
var dataModel = new DataModel();
ko.applyBindings(dataModel);
每一行具有ENTITYID和道具,其是对象本身。 这个模板是不行的,但我将如何改变它产生上述所需的表?
编辑:该props
在这个例子中是name
和lastLogin
,但我需要一个解决方案,是不可知的什么是包含内props
。
我有这个FIDDLE的那么顺利。
HTML
<div data-bind="template: { name: 'template', data: $data }"></div>
<script type="text/html" id="template">
<table>
<tr data-bind="foreach: data()">
<td data-bind="text: entityId"></td>
</tr>
</table>
</script>
Answer 1:
你总是可以创建绑定处理程序来处理的转变。
ko.bindingHandlers.foreachprop = {
transformObject: function (obj) {
var properties = [];
ko.utils.objectForEach(obj, function (key, value) {
properties.push({ key: key, value: value });
});
return properties;
},
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var properties = ko.pureComputed(function () {
var obj = ko.utils.unwrapObservable(valueAccessor());
return ko.bindingHandlers.foreachprop.transformObject(obj);
});
ko.applyBindingsToNode(element, { foreach: properties }, bindingContext);
return { controlsDescendantBindings: true };
}
};
然后应用它:
<div data-bind="template: { name: 'template', data: $data }"></div>
<script type="text/html" id="template">
<table>
<tbody data-bind="foreach: data">
<tr data-bind="foreachprop: props">
<td data-bind="text: value"></td>
</tr>
</tbody>
</table>
</script>
Answer 2:
在现代浏览器(或用适当的填充工具),你可以遍历Object.keys(obj)
该方法只返回自己的枚举的属性 ,这意味着无需额外hasOwnProperty
检查):
<table>
<tbody data-bind="foreach: {data: data, as: '_data'}">
<tr data-bind="foreach: {data: Object.keys(props), as: '_propkey'}">
<th data-bind="text: _propkey"></th>
<td data-bind="text: _data.props[_propkey]"></td>
</tr>
</tbody>
</table>
拨弄 。
注:我只是好奇,想看看这是否会工作,模板身体上面比想什么,我在生产中使用(或回来几个月后,成为像“跆拳道”)污染更严重。
自定义绑定将是一个更好的选择,我个人的喜好,虽然是使用一个计算观察到或计算观察到可写 (与工作时,后者将方便json
响应一拉宁静API)。
Answer 3:
这是杰夫的回答的修改,以保留的结合上下文
ko.bindingHandlers.eachProp = {
transformObject: function (obj) {
var properties = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
properties.push({ key: key, value: obj[key] });
}
}
return ko.observableArray(properties);
},
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor()),
properties = ko.bindingHandlers.eachProp.transformObject(value);
ko.bindingHandlers['foreach'].init(element, properties, allBindingsAccessor, viewModel, bindingContext)
return { controlsDescendantBindings: true };
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor()),
properties = ko.bindingHandlers.eachProp.transformObject(value);
ko.bindingHandlers['foreach'].update(element, properties, allBindingsAccessor, viewModel, bindingContext)
return { controlsDescendantBindings: true };
}
};
现在与父母和根适用:
<table>
<tbody data-bind="foreach: data">
<tr data-bind="eachProp: props">
<td data-bind="text: value, click: $root.doSomething"></td>
</tr>
</tbody>
</table>
Answer 4:
<table>
<tr data-bind="foreach: {data: data, as: 'item'}">
<td data-bind="foreach: { data: Object.keys(item), as: 'key' }">
<b data-bind="text: item[key]"></b>
</td>
</tr>
</table>
function DataModel(){
this.data = ko.observableArray([{
entityId: 1,
props: {
name: 'Name 1',
lastLogin: '8/5/2012'
}
},
{
entityId: 2,
props: {
name: 'Name 2',
lastLogin: '2/8/2013'
}
}]);
}
var dataModel = new DataModel();
ko.applyBindings(dataModel);
希望这是有帮助的(原谅简洁)
附录:
这里有一个工作例子已经测试...
<table class="table table-hover">
<thead>
<tr>
<!-- ko foreach: gridOptions.columnDefs -->
<th data-bind="text: displayName"></th>
<!-- /ko -->
</tr>
</thead>
<tbody>
<!-- ko foreach: {data: gridOptions.data, as: 'item'} -->
<tr>
<!-- ko foreach: {data: Object.keys(item), as: 'key'} -->
<td>
<span data-bind="text: item[key]"></span>
</td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
</table>
Answer 5:
据说,有一个更深层次的问题( 见这个线程在谷歌组 ),其是的foreach把对象作为参数的字典,而不是作为集合进行迭代。
我最好的解决办法,到目前为止是综合foreach
在Object.keys(myobject)
和“用”结合上下文。
Answer 6:
简化的答案与任何基本对象的工作,为我工作:
<!-- ko foreach: {data: Object.keys(myObj)} -->
<span data-bind="text: $data"></span>
<span data-bind="text: $parent.myObj[$data]"></span>
<!-- /ko -->
Answer 7:
(不严格遍历性,但会创建上表)
<div data-bind="template: { name: 'template', data: $data }"></div>
<script type="text/html" id="template">
<table data-bind="foreach: data()">
<tr>
<td data-bind="text: props.name"></td>
<td data-bind="text: props.lastLogin"></td>
</tr>
</table>
</script>
更新: http://jsfiddle.net/cwnEE/7/
Answer 8:
我有点晚了,但我认为这应该工作,一个简单的解决方案,而无需使用任何模板。
var json = [ { "PortfolioCompanyId":240, "dt":"2018-12-31 00:00:00.0", "ValuationDate":"2017-09-30 00:00:00.0", "capitalexpenditure":-5555660.0, "workingcapitalchange":-812350.0 }, { "PortfolioCompanyId":240, "dt":"2019-12-31 00:00:00.0", "ValuationDate":"2017-09-30 00:00:00.0", "capitalexpenditure":-5613520.0, "workingcapitalchange":-893530.0 }, { "PortfolioCompanyId":240, "dt":"2020-12-31 00:00:00.0", "ValuationDate":"2017-09-30 00:00:00.0", "capitalexpenditure":-5674130.0, "workingcapitalchange":-982850.0 }, { "PortfolioCompanyId":240, "dt":"2021-12-31 00:00:00.0", "ValuationDate":"2017-09-30 00:00:00.0", "capitalexpenditure":-6241543.0, "workingcapitalchange":-1081135.0 }, { "PortfolioCompanyId":240, "dt":"2022-12-31 00:00:00.0", "ValuationDate":"2017-09-30 00:00:00.0", "capitalexpenditure":-6865697.3, "workingcapitalchange":-1189248.5 } ]; var DataModel = function () { this.jsonArray = ko.observable(json); }; ko.applyBindings(new DataModel());
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <table class="table" data-bind="foreach:jsonArray"> <tr data-bind="foreach:Object.keys($data)"> <!-- JSON Object --> <td data-bind="text : $parent[$data]"></td> </tr> </table>
文章来源: How to use knockout to iterate over an object (not array)