knockout.js - Knockout modify portion of nested object -
i'm new knockout , struggling how update portion of view model. have wcf api returns json string containing company name , list of divisions. within each division, can contain multiple addresses , contacts. each contact can have multiple addresses. using ko.mapping map data view model, understand it, creates observables properties. can display data correctly using nested foreach loops seen in link/code below.
my problem when edit link clicked. i'm using ko.datafor(this), return entire view model. how go getting specific address or contact clicked?
javascript
$(function () { $("#addressdialog").hide(); $("#contactdialog").hide(); var data = { "companyid": 3, "companyname": "company #1", "companydivisions": [{ "addresses": [{ "address1": "1234 broadway", "address2": null, "addressid": 51135, "addresstype": { "addresstypeid": 1, "description": "mailing" }, "city": "my city", "contactid": 0, "owner": null, "state": { "statecode": "il", "stateid": 1, "statename": "illinois" }, "zip": "61234", "zipplus4": "1111" }], "contacts": [{ "addresses": [], "contactid": 8, "contacttype": { "contacttypeid": 5, "description": "supervisor" }, "companyid": 3, "firstname": "john", "lastname": "doe", "middlename": "" }], "division": { "description": "customer service", "divisioncode": "cs", "divisionid": 1 }, "xrefid": 87173 }, { "addresses": [{ "address1": "1234 broadway", "address2": "dock #2", "addressid": 51134, "addresstype": { "addresstypeid": 2, "description": "delivery" }, "city": "my city", "contactid": 0, "companyid": 3, "state": { "statecode": "il", "stateid": 1, "statename": "illinois" }, "zip": "61234", "zipplus4": "3050" }], "contacts": [{ "addresses": [], "contactid": 9, "contacttype": { "contacttypeid": 9, "description": "executive director" }, "companyid": 3, "firstname": "jane", "lastname": "doe", "middlename": "" }, { "addresses": [], "contactid": 16, "contacttype": { "contacttypeid": 13, "description": "book keeper" }, "companyid": 3, "firstname": "tony", "lastname": "adams", "middlename": null }, { "addresses": [{ "address1": "1234 broadway", "address2": null, "addressid": 51950, "addresstype": { "addresstypeid": 2, "description": "delivery" }, "city": "my city", "contactid": 17, "companyid": 3, "state": { "statecode": "il", "stateid": 1, "statename": "illinois" }, "zip": "61234", "zipplus4": null }], "contactid": 17, "contacttype": { "contacttypeid": 10, "description": "cfo" }, "companyid": 3, "firstname": "milton", "lastname": "freemon", "middlename": null }], "division": { "description": "accouting", "divisioncode": "ac", "divisionid": 4 }, "xrefid": 128438 }, { "addresses": [{ "address1": "1234 broadway", "address2": null, "addressid": 51133, "addresstype": { "addresstypeid": 2, "description": "delivery" }, "city": "my city", "state": { "statecode": "il", "stateid": 1, "statename": "illinois" }, "zip": "61234", "zipplus4": "3050" }], "contacts": [{ "addresses": [], "contactid": 10, "contacttype": { "contacttypeid": 13, "description": "programmer" }, "firstname": "jill", "lastname": "doe", "middlename": null }, { "addresses": [], "contactid": 13, "contacttype": { "contacttypeid": 7, "description": "network engineer" }, "firstname": "matt", "lastname": "williams", "middlename": null }], "division": { "description": "information technology", "divisioncode": "it", "divisionid": 2 }, "xrefid": 133320 }] }; var viewmodel = { company: ko.mapping.fromjs(data), selectedaddress: ko.observable(), selectedcontact: ko.observable(), selectaddress: function () { viewmodel.selectedaddress(this); }, selectcontact: function () { viewmodel.selectedcontact(this); }, } ko.applybindings(viewmodel); createtabs(); $(".address-edit").on("click", function () { viewmodel.selectaddress(ko.datafor(this)); $("#addressdialog").dialog({ buttons: { save: function () { $(this).dialog("close"); }, cancel: function () { $(this).dialog("close"); } } }); }); $(".contact-edit").on("click", function () { viewmodel.selectcontact(ko.datafor(this)); $("#contactdialog").dialog({ buttons: { save: function () { $(this).dialog("close"); }, cancel: function () { $(this).dialog("close"); } } }); }); }); function createtabs() { $("#tabs").tabs(); };
html
<div id="tabs" class="ui-tabs"> <div data-bind="with: company"> <h1 data-bind="text: companyname"></h1> <ul data-bind="foreach: companydivisions"> <li> <a data-bind="attr: { href: '#' + division.divisioncode(), title: division.divisioncode}, text: division.divisioncode"> <span data-bind="text: division.divisioncode"></span></a> </li> </ul> <div data-bind="foreach: companydivisions"> <div data-bind="attr: {id: division.divisioncode()}"> <h2 data-bind="text: division.description"></h2> <h3>addresses</h3> <div data-bind="foreach: addresses"> <div class="ui-widget ui-widget-content ui-corner-all box"> <b><span data-bind="text: addresstype.description"></span></b> <a href="#" class="address-edit">edit</a>| <a href="#" class="address-delete">delete</a> <br /> <span data-bind="text: address1"></span> <br /> <span data-bind="text: city"></span>, <span data-bind="text: state.statecode"></span> <span data-bind="text: zip"></span>- <span data-bind="text: zipplus4"></span> </div> </div> <br /> <div style="clear:both"></div> <h3>contacts</h3> <div data-bind="foreach: contacts"> <div class="ui-widget ui-widget-content ui-corner-all box"> <b><span data-bind="text: contacttype.description"></span></b> <a href="#" class="contact-edit">edit</a>| <a href="#" class="contact-delete">delete</a> <br /> <span data-bind="text: lastname"></span>, <span data-bind="text: firstname"></span> <span data-bind="text: middlename"></span> <br /> <div data-bind="foreach: addresses"> <br /> <b><span data-bind="text: addresstype.description"></span></b> <br /> <span data-bind="text: address1"></span> <br /> <span data-bind="text: city"></span>, <span data-bind="text: state.statecode"></span> <span data-bind="text: zip"></span>- <span data-bind="text: zipplus4"></span> </div> </div> </div> <div style="clear:both"></div> </div> </div> </div> </div> <div id="addressdialog" data-bind="with: selectedaddress">address : <input type="text" data-bind="value: address1" /> <br />city : <input type="text" data-bind="value: city" /> <br />zip : <input type="text" data-bind="value: zip" /> <br /> </div> <div id="contactdialog" data-bind="with: selectedcontact">first : <input type="text" data-bind="value: firstname" /> <br />middle : <input type="text" data-bind="value: middlename" /> <br />last : <input type="text" data-bind="value: lastname" /> <br /> </div>
thanks in advance assistance,
greg
i have updated view model little bit , remove jquery on click binding instead of have used knockout click binding.
var viewmodel = { company: ko.mapping.fromjs(data), selectedaddress: ko.observable(), selectedcontact: ko.observable(), selectaddress: function () { viewmodel.selectedaddress(this); }, selectcontact: function () { viewmodel.selectedcontact(this); }, edit: function (d) { viewmodel.selectedaddress(d); $("#addressdialog").dialog({ buttons: { save: function () { $(this).dialog("close"); }, cancel: function () { $(this).dialog("close"); } } }); }, contactedit: function (d) { viewmodel.selectedcontact(d); $("#contactdialog").dialog({ buttons: { save: function () { $(this).dialog("close"); }, cancel: function () { $(this).dialog("close"); } } }); } } ko.applybindings(viewmodel);
html
<a href="#" data-bind="click: $root.edit" class="address-edit">edit</a> <a href="#" data-bind="click: $root.contactedit" class="contact-edit">edit</a>
Comments
Post a Comment