javascript - How do I call my viewmodel function from its view - child of viewmodel (knockout.js) -
i have view called agency , viewmodel. viewmodel has property called agency data contained. data has children on view function doesn't fire when child.
<section class="view"> <header> <button class="btn btn-info btn-force-refresh pull-right" data-bind="click: refresh"> <i class="icon-refresh"></i>refresh</button> <button class="btn btn-info" data-bind="click: save"> <i class="icon-save"></i>submit data</button> <br /> <br /> <h3 class="page-title" data-bind="text: title"></h3> <div class="article-counter"> <address data-bind="text: agency().length"></address> <address>found</address> </div> </header> <table> <thead> <tr> <th>agency name</th> <th>category</th> <th>url</th> <th>number of employees</th> </tr> </thead> <tbody data-bind="foreach: agency"> <tr> <td> <!--<input data-bind="value: agencyname" /></td>--> <input data-bind="value: agencyname, event: { change: $parent.cacheform }" /> <td> <input data-bind="value: category, event: { change: $parent.cacheform }" /></td> <td> <input data-bind="value: url, event: { change: $parent.cacheform }" /></td> <td> <input data-bind="value: numberofemployees, event: { change: $parent.cacheform }" /></td> </tr> <tr> <td>activities</td> <td>declared billings</td> <td>campaigned billings</td> </tr> <tr> <td> <input data-bind="value: activities, event: { change: $parent.cacheform }" /></td> <td> <input data-bind="value: declaredbillings, event: { change: $parent.cacheform }" /></td> <td> <input data-bind="value: campaignbillings, event: { change: $parent.cacheform }" /></td> </tr> </tbody> </table> <div class="article-counter"> <div data-bind="foreach: agency"> <address data-bind="text: offices().length"></address> <address>found</address> </div> </div> <div data-bind="foreach: agency"> <div data-bind="foreach: offices"> <table> <tr> <td> <h1>offices</h1> </td> </tr> <tr> <td> <div> <table> <tr> <td>address1</td> <td>address2</td> <td>address3</td> <td>address4</td> </tr> <tr> <td> <input data-bind="value: address1, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: address2, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: address3, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: address4, event: { change: $parent.cacheform }" /> </td> </tr> <tr> <td>address5</td> <td>faxnumber</td> <td>postcode</td> <td>telephonenumber</td> </tr> <tr> <td> <input data-bind="value: address5, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: faxnumber, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: postcode, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: telephonenumber, event: { change: $parent.cacheform }" /> </td> </tr> </table> </div> </td> </tr> <tr> <td> <div class="article-counter"> <address data-bind="text: contacts().length"></address> <address>found</address> </div> </td> </tr> <tr> <td> <div data-bind="foreach: contacts"> <table> <tr> <td>title</td> <td>first name</td> <td>surname</td> </tr> <tr> <td> <input data-bind="value: title, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: firstname, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: surname, event: { change: $parent.cacheform }" /> </td> </tr> </table> </div> </td> </tr> </table> </div> </div> </section>
when change these values example function fires, parent.
<tbody data-bind="foreach: agency"> <tr> <td> <!--<input data-bind="value: agencyname" /></td>--> <input data-bind="value: agencyname, event: { change: $parent.cacheform }" /> <td> <input data-bind="value: category, event: { change: $parent.cacheform }" /></td> <td> <input data-bind="value: url, event: { change: $parent.cacheform }" /></td> <td> <input data-bind="value: numberofemployees, event: { change: $parent.cacheform }" /></td> </tr>
when loop inside each agency , each office this:
<div data-bind="foreach: agency"> <div data-bind="foreach: offices"> <table> <tr> <td> <h1>offices</h1> </td> </tr> <tr> <td> <div> <table> <tr> <td>address1</td> <td>address2</td> <td>address3</td> <td>address4</td> </tr> <tr> <td> <input data-bind="value: address1, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: address2, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: address3, event: { change: $parent.cacheform }" /> </td> <td> <input data-bind="value: address4, event: { change: $parent.cacheform }" /> </td> </tr>
this function won't fire
<input data-bind="value: address1, event: { change: $parent.cacheform }" />
i don't know correct syntax fire function agency.office.
this entire viewmodel
define(['services/datacontext'], function (datacontext) { var initialized = false; var agency; if (localstorage.agency && localstorage.offices && localstorage.contacts) { var objagency = new object(ko.mapping.fromjson(localstorage.getitem('agency'))); var objoffices = new object(ko.mapping.fromjson(localstorage.getitem('offices'))); var objcontacts = new object(ko.mapping.fromjson(localstorage.getitem('contacts'))); objagency.offices = objoffices; objagency.offices._latestvalue[0].contacts = objcontacts; agency = ko.observablearray([ko.mapping.fromjs(objagency)]); ko.applybindings(agency); initialized = true; } else { agency = ko.observablearray([]); } var save = function (agency, mystoredvalue) { // clear cache because user submitted form. don't have hold onto data anymore. //amplify.store("agency", null); return datacontext.savechanges(agency); }; var vm = { // view model, functions bound it. //these wired agency view activate: activate, agency: agency, title: 'agency', refresh: refresh, // call refresh function calls agencies save: save, cacheform: cacheform }; return vm; function activate() { vm.agency; if (initialized) { return; } initialized = false; return refresh(); } function refresh() { return datacontext.getagency(agency); } function cacheform(agency) { // object agency vm var agency = ko.tojs(agency); var s = yui().use("json-stringify", function (y) { var jsonstragency = y.json.stringify(agency, ["activities", "agencyname", "agencyid", "campaignbillings", "category", "declaredbillings", "immediateparent", "numberofemployees", "ultimateparent", "url"]); // use array of acceptable object key names whitelist. var jsonstroffices, jsonstrcontacts; (i in agency.offices) { jsonstroffices = y.json.stringify(agency.offices, ["address1", "address2", "address3", "address4", "address5", "agencyid", "faxnumber", "officeid", "postcode", "telephonenumber"]); (ii in agency.offices[i].contacts) { jsonstrcontacts = y.json.stringify(agency.offices[i].contacts, ["agencyid", "emailaddress", "firstname", "jobname", "officeid", "personid", "surname", "title"]); } } localstorage.setitem('agency', jsonstragency); localstorage.setitem('offices', jsonstroffices); localstorage.setitem('contacts', jsonstrcontacts); }); } });
if question doesn't make sense can try explain better. new using knockout don't know how best explain it.
if want go way root view model, can use $root
instead of $parent
. if want walk scopes, can use $parents
array.
if understand structure looks either $root.cacheform
or $parents[1].cacheform
work. note item passed "office".
you can alternatively handle purely on view model side using computed observable grab dependencies on of things care about. this: http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html
Comments
Post a Comment