knockout.js - KnockoutJS - Convention based auto-mapping using mapping plugin not working as expected -


i trying grips knockoutjs. have had bit of success replicating steven sanderson's seminar example mix11 (person friends on twitter) .

i trying extend can json asp.net mvc4 controller, , automatically bind data viewmodel.

i managed working quite manual mapping of json object knockout objects observables, however, simple model low complexity. when come use real, models more complicated, , manual mapping less attractive.

i think being asp.net mvc4 page irrelevant, getting valid json markup.

here full mark up:

<!doctype html> <html> <head>     <meta charset="utf-8" />     <meta name="viewport" content="width=device-width" />     <title>person</title>     <link href="/knockoutsample/content/site.css" rel="stylesheet"/>      <script src="/knockoutsample/scripts/jquery-2.0.0.js"></script>      <script src="/knockoutsample/scripts/modernizr-2.6.2.js"></script> <script src="/knockoutsample/scripts/knockout-2.2.1.debug.js"></script> <script src="/knockoutsample/scripts/knockout.mapping-latest.js"></script>  </head> <body>     <h2>person</h2> <p>full name: <span data-bind="text: fullname" ></span></p>  <p>first name: <input type="text" data-bind="value: firstname" /></p> <p>last name: <input type="text" data-bind="value: lastname" /></p>   <h2>friends (<span data-bind="text: friends().length"></span>)</h2> <ol data-bind="template: { name: 'friendstemplate', foreach:friends}"></ol>  <script id="friendstemplate" type="text/html">     <li>         <input data-bind="value: fullname"/>         <button data-bind="click: removefriend">remove</button>         <label><input type="checkbox" data-bind="checked: isontwitter" />is on twitter</label>         <input type="text" placeholder="please enter username" data-bind="value: twittername, visible: isontwitter" />     </li> </script> <button data-bind="click: addfriend, enable: friends().length < 5">add friend</button> <button data-bind="click: save">save</button>    <script type="text/javascript">      function friend() {          function instanceofconstructor(newfriend) {             return {                 fullname: newfriend.fullname,                 isontwitter: newfriend.isontwitter,                 twittername: newfriend.twittername,                 removefriend: function () {                     viewmodel.friends.remove(this);                 }             };         }         function paramatisedconstructor(name, ontwitter, twittername) {             return {                 fullname: ko.observable(name),                 isontwitter: ko.observable(ontwitter),                 twittername: ko.observable(twittername),                 removefriend: function () {                     viewmodel.friends.remove(this);                 }             };         }          switch (arguments.length) {             case 1 :                 return instanceofconstructor(arguments[0]);             case 3 :                 return paramatisedconstructor(arguments[0], arguments[1], arguments[2]);         }     }       var viewmodel = {         firstname : ko.observable(),         lastname: ko.observable(),         friends: ko.observablearray(),         addfriend: function () {             this.friends.push(new friend("new friend", false, null));         },         save: function () {             $.ajax({                 url: "/knockoutsample/main/person",                 type: "post",                 data: ko.tojson(this),                 contenttype: "application/json",             }).success(function(result){                 alert(result.message);             }).fail(function (data) {                 alert(data);             });         }     };      viewmodel.fullname = ko.dependentobservable(function () {         return this.firstname() + " " + this.lastname();     }, viewmodel);      ko.applybindings(viewmodel);      var initialdata = '{"firstname":"ian","lastname":"robertson","friends":[{"isontwitter":false,"twittername":"","fullname":"friend one"},{"isontwitter":true,"twittername":"@friendtwo","fullname":"friend two"}]}';      var tmp = ko.mapping.fromjson(initialdata);      //convention based auto-mapping not work     //ko.mapping.fromjson(initialdata, viewmodel);      //manual mapping work     viewmodel.firstname(tmp.firstname());     viewmodel.lastname(tmp.lastname());      $.each(tmp.friends(), function (i, _friend) {         viewmodel.friends.push(new friend(_friend));     });  </script>  </body> </html> 

i hoping possible avoid manual mapping @ end:

    //convention based auto-mapping not work     //ko.mapping.fromjson(initialdata, viewmodel);      //manual mapping work     viewmodel.firstname(tmp.firstname());     viewmodel.lastname(tmp.lastname());      $.each(tmp.friends(), function (i, _friend) {         viewmodel.friends.push(new friend(_friend));     }); 

any pointers on how can use mapping plugin avoid manual mapping appreciated.

update:

<script type="text/javascript">  function friend(name, ontwitter, twittername) {     return {         fullname: ko.observable(name),         isontwitter: ko.observable(ontwitter),         twittername: ko.observable(twittername),         removefriend: function () {             viewmodel.friends.remove(this);         }     }; }  var initialdata = '@html.raw(viewbag.initialdata)';  var viewmodel = {     firstname: ko.observable(),     lastname: ko.observable(),     friends: ko.observablearray() };  viewmodel = ko.mapping.fromjson(initialdata, viewmodel);  viewmodel.save = function () {     $.ajax({         url: "@url.action("person")",         type: "post",         data: ko.tojson(this),         contenttype: "application/json",     }).success(function (result) {         alert(result.message);     }).fail(function (data) {         alert(data);     }); };  viewmodel.addfriend = function () {     this.friends.push(new friend("new friend", false, null)); };  try {      viewmodel.fullname = ko.dependentobservable(function () {         return this.firstname() + " " + this.lastname();     }, viewmodel);      $.each(viewmodel.friends(), function (i, _friend) {         _friend.removefriend = function () {             viewmodel.friends.remove(this);         }     });      ko.applybindings(viewmodel);  } catch (e) {     alert(e); } 

this solution wanted achieve. thing continue try , improve upon using jquery $.each function add "removefriend" function each friend element in array.

you can use fromjs , tojs functions map viewmodel raw data , viewmodel.

var tmp = ko.mapping.fromjs(ko.mapping.tojs(viewmodel)); 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

CSS3 Transition to highlight new elements created in JQuery -