knockout.js - dynamic column and rows with knockoutjs -
my input parameter code below tablename,
i able query data return in json format, however, not able display rows item of data. idea did wrong?
<script> var invtype = "@viewbag.invtype"; function viewmodel() { var self = this; function colname(tbstruct){ this.columnname = tbstruct.columnname } self.tbstruct = ko.observablearray(); self.items = ko.observablearray(); self.invtype = invtype; self.load = function () { //expected data self.items //[{"$id":"1","id":2,"inv_id":"pv0001-1","acx_no":"6","acx_name":"abc","s_no":"5", "acc_class":"local","direction":"two-way"},{"$id":"2","id":2,"inv_id":"pv0002-1","acx_no":"3","acx_name":"ckd","s_no":"6", "acc_class":"local","direction":"two-way"}] $.ajax({ url: "@url.content("~/api/")"+self.invtype, type: 'get', datatype: 'json', success: function (data) { // map returned json view model self.items = data; } }); //expected data //[{"$id":"1","columnname":"id","system_type_id":56,"primarycol":1}, {"$id":"2","columnname":"inv_id","system_type_id":231,"primarycol":0},{"$id":"3","columnname":"acx_no","system_type_id":175,"primarycol":0},{"$id":"4","columnname":"acx_name","system_type_id":175,"primarycol":0},{"$id":"5","columnname":"s_no","system_type_id":175,"primarycol":0} {"$id":"27","columnname":"acc_class","system_type_id":231,"primarycol":0},{"$id":"28","columnname":"direction","system_type_id":231,"primarycol":0} ] $.ajax({ url: "@url.content("~/api/inventories/")"+self.invtype, type: 'get', datatype: 'json', success: function (data) { // map returned json view model $.each(data,function(i,dt){ //console.log(dt.columnname); self.tbstruct.push(new colname(dt)); }); //console.dir(self.tbstruct); } }); return self; }; } var view = new viewmodel(); ko.applybindings(view.load());
here trying display them out.
<thead> <tr data-bind="foreach: tbstruct"> <th data-bind="text: columnname"></th> </tr> </thead> <tbody > <tr data-bind="foreach: items" > <td data-bind="text:$data"></td> </tr> </tbody> </table>
function viewmodel() { var self = this; self.invtype = "@viewbag.invtype"; self.columns = ko.observablearray(); self.rows = ko.observablearray(); self.load = function () { $.when( $.get("@url.content('~/api/inventories/')" + self.invtype), $.get("@url.content('~/api/')" + self.invtype) ) .then(function (columnresponse, rowresponse) { var columndefs = columnresponse[0], rowdefs = rowresponse[0], columnmapping = { key: function (data) { return ko.utils.unwrapobservable(data.columnname); } }, rowmapping = { key: function (data) { return ko.utils.unwrapobservable(data.id); } }; ko.mapping.fromjs(columndefs, columnmapping, self.columns); ko.mapping.fromjs(rowdefs, rowmapping, self.rows); }); return self; }; }
notes:
- using jquery's
.when()
,.then()
ensures view model processing occurs after both html requests have returned successfully. see jquery's documentation on topic. - the
key
function in custom mapping ensures when callload()
again appropriate parts of view model update. otherwiseko.mapping.fromjs
replace entire observable, resulting in complete re-build of affected part of page. specifyingkey
allows partial page updates, use unique property of data here. (if don't plan on refreshing data server during page life time step might not necessary.) - the use of
ko.utils.unwrapobservable()
mandatory because during load operationkey
used on both existing view model contents and server response, exampledata.columnname
observable or raw value. - be sure read through advanced section of mapping plugin documentation, might find other helpful bits.
html
<table> <thead> <tr data-bind="foreach: $root.columns"> <th data-bind="text: columnname"></th> </tr> </thead> <tbody data-bind="foreach: $root.rows"> <tr data-bind="foreach: $root.columns"> <td data-bind="text: $parent[columnname()]"></td> </tr> </tbody> </table>
notes:
- the place
$root
necessary in<tr data-bind="foreach: $root.columns">
binding. others included consistency. $parent
refers rowforeach: $root.rows
.- the parentheses in
$parent[columnname()]
necessary becausecolumnname
observable , in complex binding not unwrapped automatically.
the whole thing can seen here: http://jsfiddle.net/tomalak/a6t8p/
, here (extended version): http://jsfiddle.net/tomalak/a6t8p/1
Comments
Post a Comment