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 call load() again appropriate parts of view model update. otherwise ko.mapping.fromjs replace entire observable, resulting in complete re-build of affected part of page. specifying key 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 operation key used on both existing view model contents and server response, example data.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 row foreach: $root.rows.
  • the parentheses in $parent[columnname()] necessary because columnname 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

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -