javascript - knockout.js foreach binding: property value to array of column names -
i have question knockout foreach binding table.
i have array of columnnames , array of items.
the items array has property called columnname. how use knockout foreach bind self.items self.columnnames?
my view model looks this:
var vm = function () { var self = this; self.items = ko.observablearray(); self.columnnames = [ "name", "age", "job"]; }; var vm = new vm(); ko.applybindings(vm); vm.items.push([ { 'columnname': 'name', 'value': 'john' }, { 'columnname': 'age', 'value': 25' } ]); vm.items.push([ { 'columnname': 'name', 'value': 'jane' }, { 'columnname': 'age', 'value': 26 }, { 'columnname': 'job', 'value': 'developer' } ]);
in view, i'm guessing need this,
<table> <thead> <tr data-bind="foreach: columnnames"> <th> <span data-bind="text: $data"></span> </th> </tr> </thead> <tbody data-bind="foreach: items"> <tr data-bind="foreach: $parent.columnnames"> <!-- how put value property here?! --> </tr> </tbody> </table>
i started jsfiddle here, http://jsfiddle.net/83zcwue7/1/
-update- i'm trying render this:
name age job john 25 jane 26 developer
-- update 2 -- created ugly (but working) solution.
http://jsfiddle.net/83zcwue7/7/
i added method call. maps columnname property name , value value, feels missed simpler solution:
self.fixeditems = ko.observablearray(); //i use in foreach self.fixdata = function(){ $.each(self.items(), function(i, rows){ var cell = new object(); $.each(rows, function(j, prop){ cell[prop.columnname] = prop.value; }); self.fixeditems.push( cell ); }); };
original data looked this:
[[{ 'columnname': 'name', 'value': 'john' }, { 'columnname': 'age', 'value': 25 }], [{ 'columnname': 'name', 'value': 'jane' }, { 'columnname': 'age', 'value': 22 }, { 'columnname': 'job', 'value': 'developer' }]]
the result (self.fixeditems) looks this:
[{ age: 25 name: "john" }, { age: 26, job: "developer", name: "jane" }]
which 'fixes' data, can used in foreach. feels missed elegant solution.
the name of items' properties must same of columnnames
. can access property of items
. this:
var vm = function () { var self = this; self.items = ko.observablearray(); self.columnnames = [ "name", "age", "job"]; }; var vm = new vm(); ko.applybindings(vm); vm.items([ { 'name': 'jonn', 'age': '10', 'job': 'developer' }, { 'name': 'jonn', 'age': '25', 'job': 'developer' } ] );
html
<table> <thead> <tr data-bind="foreach: columnnames"> <th> <span data-bind="text: $data"></span> </th> </tr> </thead> <tbody data-bind="foreach: items"> <tr data-bind="foreach: $root.columnnames"> <td data-bind="text: $parent[$data]"></td> </tr> </tbody> </table>
http://jsfiddle.net/83zcwue7/3/
edit
a clear solution using knockout functions , computed observables:
var vm = function () { var self = this; self.items = ko.observablearray(); self.columnnames = [ "name", "age", "job"]; self.fixeditems = ko.computed(function () { return ko.utils.arraymap(self.items(), function (item) { var fixeditem = {}; ko.utils.arrayforeach(item, function(column) { fixeditem[column.columnname] = column.value; }); return fixeditem; }); }); }; var vm = new vm(); ko.applybindings(vm); vm.items.push([ { 'columnname': 'name', 'value': 'john' }, { 'columnname': 'age', 'value': '25' } ]); vm.items.push([ { 'columnname': 'name', 'value': 'jane' }, { 'columnname': 'age', 'value': 26 }, { 'columnname': 'job', 'value': 'developer' } ]);
http://jsfiddle.net/83zcwue7/9/
it cleaner, isn't it?
Comments
Post a Comment