javascript - KnockoutJS Mapping Plugin (observableArray) -


i new knockout , having problem using mapping plugin not understand how maps json data.
sample json data similar in program:

contact: {         name : 'john',         email : 'address@domain.com',         phones : [{             phonetype : 'home phone',             phonenumber: '999-888-777'},             {             phonetype : 'business phone',             phonenumber: '444-888-777'},             }]         } 

as can see, json data contains array of phones.
used knockout mapping plugin , can bind 'name', 'email' , loop phone numbers in 'foreach: phones' no hassle until try make ko.compute on phonenumber object in array phones.

@section scripts {     <script src="~/viewmodels/contactmodel.js"></script>     <script type="text/javascript">         var viewmodel = new contactmodel(@html.raw(model.tojson()));         $(document).ready(function () {             ko.applybindings(viewmodel);         }); </script>  <label>name</label><input data-bind="value: name" /> <label>email</label><input data-bind="value: email" /> <label>phones</label> <table>   <tbody data-bind="foreach: phones">      <tr>       <td><strong data-bind='text: phonetype'></strong></td>       <td><input data-bind='value: phonenumber' /></td>      </tr>    /tbody>  </table> 

this contactmodel.js

    var contactmodel = function (data) {     var self = this;     ko.mapping.fromjs(data, {}, self);      self.reformatphonenumber = ko.computed(function(){     var newnumber;     newnumber = '+(1)' + self.phones().phonenumber;     return newnumber;     });      }; 

for visual representation how looks right now:

name: john email: address@domain.com phones: <--foreach: phones --> home phone: 999-888-777 business phone: 444-888-777 

what im trying reformat phonenumber display way:

name: john email: address@domain.com phones: <--foreach: phones --> home phone: (+1)999-888-777 business phone: (+1)444-888-777 

i try using reformatphonenumber in place of phonenumber in binding this:

<table>       <tbody data-bind="foreach: phones">          <tr>           <td><strong data-bind='text: phonetype'></strong></td>           <td><input data-bind='value: $root.reformatphonenumber' /></td>          </tr>        /tbody>      </table> 

but when do, value of reformatphonenumber doesn't appear. read somewhere here have make objects inside observablearray observable because ko.mapping doesn't default. cannot picture how expecting ko.mapping plugin job automatically me new jslibrary.
appreciated. thank much!!

your use of naming (a computed named reformatphonenumber) suggests think of computeds functions. while are, technically, functions, represent values. treat them values, treat observables. in case means should called more formattedphonenumber , should live property of phone number, not property of contact.

separate models individual units can bootstrap raw data.

the smallest unit of information in model hierarchy phone number:

function phonenumber(data) {     var self = this;      self.phonetype = ko.observable();     self.phonenumber = ko.observable();     self.formattedphonenumber = ko.purecomputed(function () {         return '+(1) ' + ko.unwrap(self.phonenumber);     });      ko.mapping.fromjs(data, phonenumber.mapping, self); } phonenumber.mapping = {}; 

next in hierarchy contact. contains phone numbers.

function contact(data) {     var self = this;      self.name = ko.observable();     self.email = ko.observable();     self.phones = ko.observablearray();      ko.mapping.fromjs(data, contact.mapping, self); } contact.mapping = {     phones: {         create: function (options) {             return new phonenumber(options.data);         }     } }; 

next contact list (or phone book), contains contacts:

function phonebook(data) {     var self = this;      self.contacts = ko.observablearray();      ko.mapping.fromjs(data, phonebook.mapping, self); } phonebook.mapping = {     contacts: {         create: function (options) {             return new contact(options.data);         }     } }; 

now can create entire object graph instantiating phonebook object:

var phonebookdata = {     contacts: [{         name: 'john',         email: 'address@domain.com',         phones: [{             phonetype: 'home phone',             phonenumber: '999-888-777'         }, {             phonetype: 'business phone',             phonenumber: '444-888-777'         }]     }] }; var phonebook = new phonebook(phonebookdata); 

read through documentation of mapping plugin.

expand following code snippet see work.

function phonebook(data) {      var self = this;        self.contacts = ko.observablearray();            ko.mapping.fromjs(data, phonebook.mapping, self);  }  phonebook.mapping = {      contacts: {          create: function (options) {              return new contact(options.data);          }      }  };  // ------------------------------------------------------------------    function contact(data) {      var self = this;            self.name = ko.observable();      self.email = ko.observable();      self.phones = ko.observablearray();            ko.mapping.fromjs(data, contact.mapping, self);  }  contact.mapping = {      phones: {          create: function (options) {              return new phonenumber(options.data);          }      }  };  // ------------------------------------------------------------------    function phonenumber(data) {      var self = this;            self.phonetype = ko.observable();      self.phonenumber = ko.observable();      self.formattedphonenumber = ko.purecomputed(function () {          return '+(1) ' + ko.unwrap(self.phonenumber);      });            ko.mapping.fromjs(data, phonenumber.mapping, self);  }  phonenumber.mapping = {};  // ------------------------------------------------------------------    var phonebook = new phonebook({      contacts: [{          name: 'john',          email: 'address@domain.com',          phones: [{              phonetype: 'home phone',              phonenumber: '999-888-777'          }, {              phonetype: 'business phone',              phonenumber: '444-888-777'          }]      }]  });    ko.applybindings(phonebook);
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>  <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>    <ul data-bind="foreach: contacts">      <li>          <div data-bind="text: name"></div>          <div data-bind="text: email"></div>          <ul data-bind="foreach: phones">              <li>                  <span data-bind="text: phonetype"></span>:                  <span data-bind="text: formattedphonenumber"></span>              </li>          </ul>      </li>  </ul>    <hr />  model data:  <pre data-bind="text: ko.tojson(ko.mapping.tojs($root), null, 2)"></pre>    viewmodel data:  <pre data-bind="text: ko.tojson($root, null, 2)"></pre>


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -